1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: RISCV31 PATCH.
15 *
16 * Create: 2022-2-12
17 */
18 #include "chip_io.h"
19 #include "arch_barrier.h"
20 #include "flash_patch.h"
21
22 #define RISCV31_PATCH_FLPCTRL 0xE0000000
23
24 #define RISCV31_PATCH_FLPCTRL_OFFSET 0x0
25 #define RISCV31_PATCH_FLPRMP (RISCV31_PATCH_FLPCTRL + 0x4)
26
27 #define RISCV31_PATCH_FLPLACMP0 (RISCV31_PATCH_FLPCTRL + 0x8)
28 #define RISCV31_PATCH_FLPLACMP1 (RISCV31_PATCH_FLPCTRL + 0xC)
29
30 #define RISCV31_PATCH_FLPIACMP0 (RISCV31_PATCH_FLPCTRL + 0x10)
31
32 #define RISCV31_PATCH_FLPCTRL_ENABLE 0x1
33
34 #define RISCV31_PATCH_FLPCTRL_PCO_WITHIN_1M 0x0
35 #define RISCV31_PATCH_FLPCTRL_PCO_LARGER_1M 0x1
36
37 #define RISCV31_PATCH_FLPCTRL_WPT_WRITABLE 0x0
38 #define RISCV31_PATCH_FLPCTRL_WPT_UNWRITABLE 0x1
39
40 #define RISCV31_PATCH_FLPCTRL_FLPLACMP0_DISABLE 0x0
41 #define RISCV31_PATCH_FLPCTRL_FLPLACMP1_DISABLE 0x0
42
43 #define RISCV31_PATCH_FP_CMP_CTRL_INDEX 0
44 #define RISCV31_PATCH_FP_CMP_REMAP_INDEX 1
45 #define RISCV31_PATCH_FP_CMP_COUNT_INDEX 2
46 #define RISCV31_PATCH_FP_CMP_MATCH_INDEX 3
47
48 typedef enum {
49 GEN_BIT0 = 0,
50 WPT_BIT1 = 1,
51 PCO_BIT2 = 2,
52 LACEN0_BIT3 = 3,
53 LACEN1_BIT4 = 4,
54 } sema_enum;
55
riscv_patch_init(riscv_cfg_t patch_cfg)56 void riscv_patch_init(riscv_cfg_t patch_cfg)
57 {
58 reg_setbit(RISCV31_PATCH_FLPCTRL, RISCV31_PATCH_FLPCTRL_OFFSET, GEN_BIT0);
59 reg_clrbit(RISCV31_PATCH_FLPCTRL, RISCV31_PATCH_FLPCTRL_OFFSET, WPT_BIT1);
60
61 if (patch_cfg.off_region == true) {
62 reg_setbit(RISCV31_PATCH_FLPCTRL, RISCV31_PATCH_FLPCTRL_OFFSET, PCO_BIT2);
63 } else {
64 reg_clrbit(RISCV31_PATCH_FLPCTRL, RISCV31_PATCH_FLPCTRL_OFFSET, PCO_BIT2);
65 }
66
67 for (uint32_t loop = 0; loop < RISCV31_PATCH_CMP_REG_NUM; loop++) {
68 *((uint32_t *)RISCV31_PATCH_FLPIACMP0 + loop) =
69 *((uint32_t *)(uintptr_t)((void *)patch_cfg.cmp_start_addr) +
70 RISCV31_PATCH_FP_CMP_MATCH_INDEX + loop);
71 }
72
73 writel(RISCV31_PATCH_FLPRMP, (uint32_t)(uintptr_t)((void *)patch_cfg.remap_addr));
74 reg_setbit(RISCV31_PATCH_FLPCTRL, RISCV31_PATCH_FLPCTRL_OFFSET, WPT_BIT1);
75 dsb();
76 }