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