forked from Mirrors/opensbi
		
	lib: utils: reset: Add T-HEAD sample platform reset driver
This driver is for T-HEAD test chip, fpga. It could work with
all T-HEAD riscv processors: C9xx series.
example1: (Using io-regs for reset)
reset: reset-sample {
	compatible = "thead,reset-sample";
	plic-delegate = <0xff 0xd81ffffc>;
	entry-reg = <0xff 0xff019050>;
	entry-cnt = <4>;
	control-reg = <0xff 0xff015004>;
	control-val = <0x1c>;
	csr-copy = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc>;
};
example2: (Using csr-regs for reset)
reset: reset-sample {
	compatible = "thead,reset-sample";
	plic-delegate = <0xff 0xd81ffffc>;
	using-csr-reset;
	csr-copy = <0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc
		    0x3b0 0x3b1 0x3b2 0x3b3
		    0x3b4 0x3b5 0x3b6 0x3b7
		    0x3a0>;
};
example3: (Only delegate plic enable to S-mode)
reset: reset-sample {
	compatible = "thead,reset-sample";
	plic-delegate = <0xff 0xd81ffffc>;
};
After this patch, all T-HEAD c9xx would use platform/generic with fw_dynamic
as default:
CROSS_COMPILE=riscv64-linux-gnu- PLATFORM=generic FW_PIC=y /usr/bin/make
The platform/thead will be deprecated.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
			
			
This commit is contained in:
		@@ -157,6 +157,11 @@ void csr_write_num(int csr_num, unsigned long val);
 | 
				
			|||||||
		__asm__ __volatile__("wfi" ::: "memory"); \
 | 
							__asm__ __volatile__("wfi" ::: "memory"); \
 | 
				
			||||||
	} while (0)
 | 
						} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ebreak()                                             \
 | 
				
			||||||
 | 
						do {                                              \
 | 
				
			||||||
 | 
							__asm__ __volatile__("ebreak" ::: "memory"); \
 | 
				
			||||||
 | 
						} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Get current HART id */
 | 
					/* Get current HART id */
 | 
				
			||||||
#define current_hartid()	((unsigned int)csr_read(CSR_MHARTID))
 | 
					#define current_hartid()	((unsigned int)csr_read(CSR_MHARTID))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,9 @@
 | 
				
			|||||||
#define RISCV_FENCE(p, s) \
 | 
					#define RISCV_FENCE(p, s) \
 | 
				
			||||||
	__asm__ __volatile__ ("fence " #p "," #s : : : "memory")
 | 
						__asm__ __volatile__ ("fence " #p "," #s : : : "memory")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define RISCV_FENCE_I \
 | 
				
			||||||
 | 
						__asm__ __volatile__ ("fence.i" : : : "memory")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Read & Write Memory barrier */
 | 
					/* Read & Write Memory barrier */
 | 
				
			||||||
#define mb()			RISCV_FENCE(iorw,iorw)
 | 
					#define mb()			RISCV_FENCE(iorw,iorw)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,10 +13,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern struct fdt_reset fdt_reset_sifive;
 | 
					extern struct fdt_reset fdt_reset_sifive;
 | 
				
			||||||
extern struct fdt_reset fdt_reset_htif;
 | 
					extern struct fdt_reset fdt_reset_htif;
 | 
				
			||||||
 | 
					extern struct fdt_reset fdt_reset_thead;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct fdt_reset *reset_drivers[] = {
 | 
					static struct fdt_reset *reset_drivers[] = {
 | 
				
			||||||
	&fdt_reset_sifive,
 | 
						&fdt_reset_sifive,
 | 
				
			||||||
	&fdt_reset_htif,
 | 
						&fdt_reset_htif,
 | 
				
			||||||
 | 
						&fdt_reset_thead,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct fdt_reset *current_driver = NULL;
 | 
					static struct fdt_reset *current_driver = NULL;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										132
									
								
								lib/utils/reset/fdt_reset_thead.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								lib/utils/reset/fdt_reset_thead.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: BSD-2-Clause
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <libfdt.h>
 | 
				
			||||||
 | 
					#include <sbi/riscv_io.h>
 | 
				
			||||||
 | 
					#include <sbi/sbi_bitops.h>
 | 
				
			||||||
 | 
					#include <sbi/sbi_hart.h>
 | 
				
			||||||
 | 
					#include <sbi/sbi_scratch.h>
 | 
				
			||||||
 | 
					#include <sbi_utils/fdt/fdt_helper.h>
 | 
				
			||||||
 | 
					#include <sbi_utils/reset/fdt_reset.h>
 | 
				
			||||||
 | 
					#include "fdt_reset_thead.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct custom_csr custom_csr[MAX_CUSTOM_CSR];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CSR_OPCODE 0x39073
 | 
				
			||||||
 | 
					static void clone_csrs(int cnt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned long i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < cnt; i++) {
 | 
				
			||||||
 | 
							/* Write csr BIT[31 - 20] to stub */
 | 
				
			||||||
 | 
							__reset_thead_csr_stub[3*i + 1] =
 | 
				
			||||||
 | 
									CSR_OPCODE | (custom_csr[i].index << 20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Mask csr BIT[31 - 20] */
 | 
				
			||||||
 | 
							*(u32 *)&__fdt_reset_thead_csrr &= BIT(20) - 1;
 | 
				
			||||||
 | 
							smp_mb();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Write csr BIT[31 - 20] to __fdt_reset_thead_csrr */
 | 
				
			||||||
 | 
							*(u32 *)&__fdt_reset_thead_csrr |= custom_csr[i].index << 20;
 | 
				
			||||||
 | 
							smp_mb();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RISCV_FENCE_I;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							custom_csr[i].value = __fdt_reset_thead_csrr();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern void __thead_pre_start_warm(void);
 | 
				
			||||||
 | 
					static int thead_reset_init(void *fdt, int nodeoff,
 | 
				
			||||||
 | 
									 const struct fdt_match *match)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						void *p;
 | 
				
			||||||
 | 
						const fdt64_t *val;
 | 
				
			||||||
 | 
						const fdt32_t *val_w;
 | 
				
			||||||
 | 
						int len, i, cnt;
 | 
				
			||||||
 | 
						u32 t, tmp = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Prepare clone csrs */
 | 
				
			||||||
 | 
						val_w = fdt_getprop(fdt, nodeoff, "csr-copy", &len);
 | 
				
			||||||
 | 
						if (len > 0 && val_w) {
 | 
				
			||||||
 | 
							cnt = len / sizeof(fdt32_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (cnt > MAX_CUSTOM_CSR)
 | 
				
			||||||
 | 
								sbi_hart_hang();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (i = 0; i < cnt; i++) {
 | 
				
			||||||
 | 
								custom_csr[i].index = fdt32_to_cpu(val_w[i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cnt)
 | 
				
			||||||
 | 
							clone_csrs(cnt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Delegate plic enable regs for S-mode */
 | 
				
			||||||
 | 
						val = fdt_getprop(fdt, nodeoff, "plic-delegate", &len);
 | 
				
			||||||
 | 
						if (len > 0 && val) {
 | 
				
			||||||
 | 
							p = (void *)(ulong)fdt64_to_cpu(*val);
 | 
				
			||||||
 | 
							writel(BIT(0), p);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Old reset method for secondary harts */
 | 
				
			||||||
 | 
						if (fdt_getprop(fdt, nodeoff, "using-csr-reset", &len)) {
 | 
				
			||||||
 | 
							csr_write(0x7c7, (ulong)&__thead_pre_start_warm);
 | 
				
			||||||
 | 
							csr_write(0x7c6, -1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Custom reset method for secondary harts */
 | 
				
			||||||
 | 
						val = fdt_getprop(fdt, nodeoff, "entry-reg", &len);
 | 
				
			||||||
 | 
						if (len > 0 && val) {
 | 
				
			||||||
 | 
							p = (void *)(ulong)fdt64_to_cpu(*val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							val_w = fdt_getprop(fdt, nodeoff, "entry-cnt", &len);
 | 
				
			||||||
 | 
							if (len > 0 && val_w) {
 | 
				
			||||||
 | 
								tmp = fdt32_to_cpu(*val_w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for (i = 0; i < tmp; i++) {
 | 
				
			||||||
 | 
									t = (ulong)&__thead_pre_start_warm;
 | 
				
			||||||
 | 
									writel(t, p + (8 * i));
 | 
				
			||||||
 | 
									t = (u64)(ulong)&__thead_pre_start_warm >> 32;
 | 
				
			||||||
 | 
									writel(t, p + (8 * i) + 4);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							val = fdt_getprop(fdt, nodeoff, "control-reg", &len);
 | 
				
			||||||
 | 
							if (len > 0 && val) {
 | 
				
			||||||
 | 
								p = (void *)(ulong)fdt64_to_cpu(*val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								val_w = fdt_getprop(fdt, nodeoff, "control-val", &len);
 | 
				
			||||||
 | 
								if (len > 0 && val_w) {
 | 
				
			||||||
 | 
									tmp = fdt32_to_cpu(*val_w);
 | 
				
			||||||
 | 
									tmp |= readl(p);
 | 
				
			||||||
 | 
									writel(tmp, p);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int thead_system_reset_check(u32 type, u32 reason)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void thead_system_reset(u32 type, u32 reason)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ebreak();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct fdt_match thead_reset_match[] = {
 | 
				
			||||||
 | 
						{ .compatible = "thead,reset-sample" },
 | 
				
			||||||
 | 
						{ },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fdt_reset fdt_reset_thead = {
 | 
				
			||||||
 | 
						.match_table = thead_reset_match,
 | 
				
			||||||
 | 
						.init = thead_reset_init,
 | 
				
			||||||
 | 
						.system_reset_check = thead_system_reset_check,
 | 
				
			||||||
 | 
						.system_reset = thead_system_reset
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										23
									
								
								lib/utils/reset/fdt_reset_thead.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								lib/utils/reset/fdt_reset_thead.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: BSD-2-Clause
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __FDT_RESET_THEAD_H__
 | 
				
			||||||
 | 
					#define __FDT_RESET_THEAD_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_CUSTOM_CSR	32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __ASSEMBLER__
 | 
				
			||||||
 | 
					struct custom_csr {
 | 
				
			||||||
 | 
						unsigned long index;
 | 
				
			||||||
 | 
						unsigned long value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u64  __fdt_reset_thead_csrr(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern struct custom_csr custom_csr[MAX_CUSTOM_CSR];
 | 
				
			||||||
 | 
					extern u32 __reset_thead_csr_stub[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __ASSEMBLER__ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __FDT_RESET_THEAD_H__ */
 | 
				
			||||||
							
								
								
									
										47
									
								
								lib/utils/reset/fdt_reset_thead_asm.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								lib/utils/reset/fdt_reset_thead_asm.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: BSD-2-Clause
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sbi/riscv_asm.h>
 | 
				
			||||||
 | 
					#include "fdt_reset_thead.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * csrrs rd, csr, rs1
 | 
				
			||||||
 | 
					 * |31   20|19   15|14   12|11  7|6       0|
 | 
				
			||||||
 | 
					 *    csr     rs1     010     rd   1110011
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define CSR_STUB	addi    x0, x0, 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.option norvc
 | 
				
			||||||
 | 
						.align 3
 | 
				
			||||||
 | 
						.global __fdt_reset_thead_csrr
 | 
				
			||||||
 | 
					__fdt_reset_thead_csrr:
 | 
				
			||||||
 | 
						csrrs a0, 0, x0
 | 
				
			||||||
 | 
						ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.align 3
 | 
				
			||||||
 | 
						.global __thead_pre_start_warm
 | 
				
			||||||
 | 
					__thead_pre_start_warm:
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Clear L1 cache & BTB & BHT ...
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						li	t1, 0x70013
 | 
				
			||||||
 | 
						csrw	0x7c2, t1
 | 
				
			||||||
 | 
						fence rw,rw
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lla	t1, custom_csr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.global __reset_thead_csr_stub
 | 
				
			||||||
 | 
					__reset_thead_csr_stub:
 | 
				
			||||||
 | 
					.rept	MAX_CUSTOM_CSR
 | 
				
			||||||
 | 
						REG_L	t2, 8(t1)
 | 
				
			||||||
 | 
						CSR_STUB
 | 
				
			||||||
 | 
						addi	t1, t1, 16
 | 
				
			||||||
 | 
					.endr
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Clear L1 cache & BTB & BHT ...
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						li	t1, 0x70013
 | 
				
			||||||
 | 
						csrw	0x7c2, t1
 | 
				
			||||||
 | 
						fence rw,rw
 | 
				
			||||||
 | 
						j _start_warm
 | 
				
			||||||
@@ -10,3 +10,5 @@
 | 
				
			|||||||
libsbiutils-objs-y += reset/fdt_reset.o
 | 
					libsbiutils-objs-y += reset/fdt_reset.o
 | 
				
			||||||
libsbiutils-objs-y += reset/fdt_reset_htif.o
 | 
					libsbiutils-objs-y += reset/fdt_reset_htif.o
 | 
				
			||||||
libsbiutils-objs-y += reset/fdt_reset_sifive.o
 | 
					libsbiutils-objs-y += reset/fdt_reset_sifive.o
 | 
				
			||||||
 | 
					libsbiutils-objs-y += reset/fdt_reset_thead.o
 | 
				
			||||||
 | 
					libsbiutils-objs-y += reset/fdt_reset_thead_asm.o
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user