1 /*
2 * SPDX-FileCopyrightText: 2019-2025 SiFli Technologies(Nanjing) Co., Ltd
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "bf0_hal.h"
8 #include "bf0_hal_patch.h"
9 #include "register.h"
10
11 #if defined(HAL_LCPU_PATCH_MODULE)
HAL_PATCH_install2(struct patch_entry_desc * patch_entries,uint32_t size,int cer)12 __USED int HAL_PATCH_install2(struct patch_entry_desc *patch_entries, uint32_t size, int cer)
13 {
14 int r = 0;
15 int i;
16 uint32_t data;
17 __IO uint32_t *p_a = (__IO uint32_t *)PATCH_BASE;
18
19 hwp_patch->CER = 0;
20 for (i = 0; i < (int)size ; i++, patch_entries++)
21 {
22 int pn = i + (cer ? PATCH_AON : 0);
23 if (cer == 0 || (cer & (1UL << pn)))
24 {
25 *(p_a + pn) = (patch_entries->break_addr & PATCH_CH0_ADDR_Msk);
26 data = patch_entries->data;
27 hwp_patch->CSR = (1UL << pn);
28 hwp_patch->CDR = data;
29 r |= (1UL << pn);
30 }
31 }
32 hwp_patch->CSR = 0;
33 hwp_patch->CER = cer ? cer : r;
34 return r;
35 }
36
37 typedef void (hook_install_type)(void);
HAL_PATCH_GetEntryAddr(void)38 __WEAK uint32_t *HAL_PATCH_GetEntryAddr(void)
39 {
40 return (uint32_t *)LCPU_PATCH_RECORD_ADDR;
41 }
42
HAL_PATCH_install(void)43 __USED int HAL_PATCH_install(void)
44 {
45 uint32_t *p = (uint32_t *)HAL_PATCH_GetEntryAddr();
46 int r = 0;
47
48 if ((*p) == PATCH_TAG)
49 {
50 uint32_t size = *(++p);
51 size /= sizeof(struct patch_entry_desc);
52 p++;
53 r = HAL_PATCH_install2((struct patch_entry_desc *)p, size, 0);
54 }
55 return r;
56 }
57
HAL_PATCH_Entry(void)58 __USED void HAL_PATCH_Entry(void)
59 {
60 uint32_t *p = (uint32_t *)HAL_PATCH_GetEntryAddr();
61
62 if ((*p) == PATCH_TAG)
63 {
64 hook_install_type *hook_install = (hook_install_type *)(LCPU_PATCH_START_ADDR + 1);
65 hook_install();
66 }
67 }
68
HAL_PATCH_save(struct patch_entry_desc * patch_entries,uint32_t size,uint32_t * cer)69 __USED int HAL_PATCH_save(struct patch_entry_desc *patch_entries, uint32_t size, uint32_t *cer)
70 {
71 int i;
72 __IO uint32_t *p_a = (__IO uint32_t *)PATCH_BASE;
73
74 for (i = PATCH_AON; i < MAX_PATCH_ENTRIES && i < (int)(PATCH_AON + size); i++, patch_entries++)
75 {
76 if ((1UL << i) & hwp_patch->CER)
77 {
78 patch_entries->break_addr = *(p_a + i);
79 patch_entries->data = *(uint32_t *)patch_entries->break_addr;
80 }
81 else
82 break;
83 }
84 *cer = hwp_patch->CER;
85 return i - PATCH_AON;
86 }
87
88 #endif
89