forked from Mirrors/opensbi
		
	lib: sbi_platform: Add callback to populate HART extensions
We add platform specific extensions_init() callback which allows platforms to populate HART extensions for each HART. For example, the generic platform can populate HART extensions from HART ISA string described in DeviceTree. Signed-off-by: Anup Patel <apatel@ventanamicro.com> Reviewed-by: Atish Patra <atishp@rivosinc.com>
This commit is contained in:
		@@ -89,6 +89,9 @@ struct sbi_platform_operations {
 | 
			
		||||
	 */
 | 
			
		||||
	int (*misa_get_xlen)(void);
 | 
			
		||||
 | 
			
		||||
	/** Initialize (or populate) HART extensions for the platform */
 | 
			
		||||
	int (*extensions_init)(void);
 | 
			
		||||
 | 
			
		||||
	/** Initialize (or populate) domains for the platform */
 | 
			
		||||
	int (*domains_init)(void);
 | 
			
		||||
 | 
			
		||||
@@ -453,6 +456,21 @@ static inline int sbi_platform_misa_xlen(const struct sbi_platform *plat)
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize (or populate) HART extensions for the platform
 | 
			
		||||
 *
 | 
			
		||||
 * @param plat pointer to struct sbi_platform
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success and negative error code on failure
 | 
			
		||||
 */
 | 
			
		||||
static inline int sbi_platform_extensions_init(
 | 
			
		||||
					const struct sbi_platform *plat)
 | 
			
		||||
{
 | 
			
		||||
	if (plat && sbi_platform_ops(plat)->extensions_init)
 | 
			
		||||
		return sbi_platform_ops(plat)->extensions_init();
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize (or populate) domains for the platform
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -536,16 +536,17 @@ static int hart_pmu_get_allowed_bits(void)
 | 
			
		||||
	return num_bits;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void hart_detect_features(struct sbi_scratch *scratch)
 | 
			
		||||
static int hart_detect_features(struct sbi_scratch *scratch)
 | 
			
		||||
{
 | 
			
		||||
	struct sbi_trap_info trap = {0};
 | 
			
		||||
	struct hart_features *hfeatures =
 | 
			
		||||
		sbi_scratch_offset_ptr(scratch, hart_features_offset);
 | 
			
		||||
	unsigned long val, oldval;
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	/* If hart features already detected then do nothing */
 | 
			
		||||
	if (hfeatures->detected)
 | 
			
		||||
		return;
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	/* Clear hart features */
 | 
			
		||||
	hfeatures->extensions = 0;
 | 
			
		||||
@@ -680,10 +681,15 @@ __mhpm_skip:
 | 
			
		||||
					SBI_HART_EXT_SMSTATEEN, true);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Let platform populate extensions */
 | 
			
		||||
	rc = sbi_platform_extensions_init(sbi_platform_thishart_ptr());
 | 
			
		||||
	if (rc)
 | 
			
		||||
		return rc;
 | 
			
		||||
 | 
			
		||||
	/* Mark hart feature detection done */
 | 
			
		||||
	hfeatures->detected = true;
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sbi_hart_reinit(struct sbi_scratch *scratch)
 | 
			
		||||
@@ -705,6 +711,8 @@ int sbi_hart_reinit(struct sbi_scratch *scratch)
 | 
			
		||||
 | 
			
		||||
int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot)
 | 
			
		||||
{
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	if (cold_boot) {
 | 
			
		||||
		if (misa_extension('H'))
 | 
			
		||||
			sbi_hart_expected_trap = &__sbi_expected_trap_hext;
 | 
			
		||||
@@ -715,7 +723,9 @@ int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot)
 | 
			
		||||
			return SBI_ENOMEM;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hart_detect_features(scratch);
 | 
			
		||||
	rc = hart_detect_features(scratch);
 | 
			
		||||
	if (rc)
 | 
			
		||||
		return rc;
 | 
			
		||||
 | 
			
		||||
	return sbi_hart_reinit(scratch);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user