2018-12-11 21:54:06 +08:00
|
|
|
/*
|
2019-01-24 14:11:10 +08:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
*
|
|
|
|
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
|
2018-12-11 21:54:06 +08:00
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Anup Patel <anup.patel@wdc.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __SBI_SCRATCH_H__
|
|
|
|
#define __SBI_SCRATCH_H__
|
|
|
|
|
|
|
|
#include <sbi/riscv_asm.h>
|
2018-12-31 13:49:20 +08:00
|
|
|
|
2019-04-11 08:41:46 +08:00
|
|
|
/* clang-format off */
|
|
|
|
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Offset of fw_start member in sbi_scratch */
|
2019-01-02 17:21:30 +08:00
|
|
|
#define SBI_SCRATCH_FW_START_OFFSET (0 * __SIZEOF_POINTER__)
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Offset of fw_size member in sbi_scratch */
|
2019-01-02 17:21:30 +08:00
|
|
|
#define SBI_SCRATCH_FW_SIZE_OFFSET (1 * __SIZEOF_POINTER__)
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Offset of next_arg1 member in sbi_scratch */
|
2019-01-02 17:21:30 +08:00
|
|
|
#define SBI_SCRATCH_NEXT_ARG1_OFFSET (2 * __SIZEOF_POINTER__)
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Offset of next_addr member in sbi_scratch */
|
2019-01-02 17:21:30 +08:00
|
|
|
#define SBI_SCRATCH_NEXT_ADDR_OFFSET (3 * __SIZEOF_POINTER__)
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Offset of next_mode member in sbi_scratch */
|
2019-01-02 17:21:30 +08:00
|
|
|
#define SBI_SCRATCH_NEXT_MODE_OFFSET (4 * __SIZEOF_POINTER__)
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Offset of warmboot_addr member in sbi_scratch */
|
2019-01-02 17:21:30 +08:00
|
|
|
#define SBI_SCRATCH_WARMBOOT_ADDR_OFFSET (5 * __SIZEOF_POINTER__)
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Offset of platform_addr member in sbi_scratch */
|
2019-01-02 17:21:30 +08:00
|
|
|
#define SBI_SCRATCH_PLATFORM_ADDR_OFFSET (6 * __SIZEOF_POINTER__)
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Offset of hartid_to_scratch member in sbi_scratch */
|
2019-01-02 17:21:30 +08:00
|
|
|
#define SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET (7 * __SIZEOF_POINTER__)
|
2020-12-29 14:09:22 +08:00
|
|
|
/** Offset of trap_exit member in sbi_scratch */
|
|
|
|
#define SBI_SCRATCH_TRAP_EXIT_OFFSET (8 * __SIZEOF_POINTER__)
|
2019-02-19 20:41:22 +08:00
|
|
|
/** Offset of tmp0 member in sbi_scratch */
|
2020-12-29 14:09:22 +08:00
|
|
|
#define SBI_SCRATCH_TMP0_OFFSET (9 * __SIZEOF_POINTER__)
|
2019-03-27 22:57:20 +08:00
|
|
|
/** Offset of options member in sbi_scratch */
|
2020-12-29 14:09:22 +08:00
|
|
|
#define SBI_SCRATCH_OPTIONS_OFFSET (10 * __SIZEOF_POINTER__)
|
2019-05-21 14:21:01 +08:00
|
|
|
/** Offset of extra space in sbi_scratch */
|
2020-12-29 14:09:22 +08:00
|
|
|
#define SBI_SCRATCH_EXTRA_SPACE_OFFSET (11 * __SIZEOF_POINTER__)
|
2020-03-04 16:46:42 +08:00
|
|
|
/** Maximum size of sbi_scratch (4KB) */
|
|
|
|
#define SBI_SCRATCH_SIZE (0x1000)
|
2018-12-31 13:49:20 +08:00
|
|
|
|
2019-04-11 08:41:46 +08:00
|
|
|
/* clang-format on */
|
|
|
|
|
2021-03-12 19:00:01 +08:00
|
|
|
#ifndef __ASSEMBLER__
|
2018-12-31 13:49:20 +08:00
|
|
|
|
2018-12-11 21:54:06 +08:00
|
|
|
#include <sbi/sbi_types.h>
|
2019-03-09 03:22:22 +08:00
|
|
|
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Representation of per-HART scratch space */
|
2018-12-11 21:54:06 +08:00
|
|
|
struct sbi_scratch {
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Start (or base) address of firmware linked to OpenSBI library */
|
2018-12-11 21:54:06 +08:00
|
|
|
unsigned long fw_start;
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Size (in bytes) of firmware linked to OpenSBI library */
|
2018-12-11 21:54:06 +08:00
|
|
|
unsigned long fw_size;
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Arg1 (or 'a1' register) of next booting stage for this HART */
|
2018-12-11 21:54:06 +08:00
|
|
|
unsigned long next_arg1;
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Address of next booting stage for this HART */
|
2018-12-11 21:54:06 +08:00
|
|
|
unsigned long next_addr;
|
2022-10-14 08:32:39 +08:00
|
|
|
/** Privilege mode of next booting stage for this HART */
|
2018-12-11 21:54:06 +08:00
|
|
|
unsigned long next_mode;
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Warm boot entry point address for this HART */
|
2018-12-11 21:54:06 +08:00
|
|
|
unsigned long warmboot_addr;
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Address of sbi_platform */
|
2018-12-11 21:54:06 +08:00
|
|
|
unsigned long platform_addr;
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Address of HART ID to sbi_scratch conversion function */
|
2018-12-11 21:54:06 +08:00
|
|
|
unsigned long hartid_to_scratch;
|
2020-12-29 14:09:22 +08:00
|
|
|
/** Address of trap exit function */
|
|
|
|
unsigned long trap_exit;
|
2019-02-19 20:41:22 +08:00
|
|
|
/** Temporary storage */
|
|
|
|
unsigned long tmp0;
|
2019-03-27 22:57:20 +08:00
|
|
|
/** Options for OpenSBI library */
|
|
|
|
unsigned long options;
|
2021-01-11 19:15:14 +08:00
|
|
|
};
|
2018-12-11 21:54:06 +08:00
|
|
|
|
2022-03-16 18:16:48 +08:00
|
|
|
/**
|
|
|
|
* Prevent modification of struct sbi_scratch from affecting
|
|
|
|
* SBI_SCRATCH_xxx_OFFSET
|
|
|
|
*/
|
|
|
|
_Static_assert(
|
|
|
|
offsetof(struct sbi_scratch, fw_start)
|
|
|
|
== SBI_SCRATCH_FW_START_OFFSET,
|
|
|
|
"struct sbi_scratch definition has changed, please redefine "
|
|
|
|
"SBI_SCRATCH_FW_START_OFFSET");
|
|
|
|
_Static_assert(
|
|
|
|
offsetof(struct sbi_scratch, fw_size)
|
|
|
|
== SBI_SCRATCH_FW_SIZE_OFFSET,
|
|
|
|
"struct sbi_scratch definition has changed, please redefine "
|
|
|
|
"SBI_SCRATCH_FW_SIZE_OFFSET");
|
|
|
|
_Static_assert(
|
|
|
|
offsetof(struct sbi_scratch, next_arg1)
|
|
|
|
== SBI_SCRATCH_NEXT_ARG1_OFFSET,
|
|
|
|
"struct sbi_scratch definition has changed, please redefine "
|
|
|
|
"SBI_SCRATCH_NEXT_ARG1_OFFSET");
|
|
|
|
_Static_assert(
|
|
|
|
offsetof(struct sbi_scratch, next_addr)
|
|
|
|
== SBI_SCRATCH_NEXT_ADDR_OFFSET,
|
|
|
|
"struct sbi_scratch definition has changed, please redefine "
|
|
|
|
"SBI_SCRATCH_NEXT_ADDR_OFFSET");
|
|
|
|
_Static_assert(
|
|
|
|
offsetof(struct sbi_scratch, next_mode)
|
|
|
|
== SBI_SCRATCH_NEXT_MODE_OFFSET,
|
|
|
|
"struct sbi_scratch definition has changed, please redefine "
|
|
|
|
"SBI_SCRATCH_NEXT_MODE_OFFSET");
|
|
|
|
_Static_assert(
|
|
|
|
offsetof(struct sbi_scratch, warmboot_addr)
|
|
|
|
== SBI_SCRATCH_WARMBOOT_ADDR_OFFSET,
|
|
|
|
"struct sbi_scratch definition has changed, please redefine "
|
|
|
|
"SBI_SCRATCH_WARMBOOT_ADDR_OFFSET");
|
|
|
|
_Static_assert(
|
|
|
|
offsetof(struct sbi_scratch, platform_addr)
|
|
|
|
== SBI_SCRATCH_PLATFORM_ADDR_OFFSET,
|
|
|
|
"struct sbi_scratch definition has changed, please redefine "
|
|
|
|
"SBI_SCRATCH_PLATFORM_ADDR_OFFSET");
|
|
|
|
_Static_assert(
|
|
|
|
offsetof(struct sbi_scratch, hartid_to_scratch)
|
|
|
|
== SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET,
|
|
|
|
"struct sbi_scratch definition has changed, please redefine "
|
|
|
|
"SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET");
|
|
|
|
_Static_assert(
|
|
|
|
offsetof(struct sbi_scratch, trap_exit)
|
|
|
|
== SBI_SCRATCH_TRAP_EXIT_OFFSET,
|
|
|
|
"struct sbi_scratch definition has changed, please redefine "
|
|
|
|
"SBI_SCRATCH_TRAP_EXIT_OFFSET");
|
|
|
|
_Static_assert(
|
|
|
|
offsetof(struct sbi_scratch, tmp0)
|
|
|
|
== SBI_SCRATCH_TMP0_OFFSET,
|
|
|
|
"struct sbi_scratch definition has changed, please redefine "
|
|
|
|
"SBI_SCRATCH_TMP0_OFFSET");
|
|
|
|
_Static_assert(
|
|
|
|
offsetof(struct sbi_scratch, options)
|
|
|
|
== SBI_SCRATCH_OPTIONS_OFFSET,
|
|
|
|
"struct sbi_scratch definition has changed, please redefine "
|
|
|
|
"SBI_SCRATCH_OPTIONS_OFFSET");
|
|
|
|
|
2019-03-27 22:58:49 +08:00
|
|
|
/** Possible options for OpenSBI library */
|
|
|
|
enum sbi_scratch_options {
|
|
|
|
/** Disable prints during boot */
|
2019-04-11 08:41:52 +08:00
|
|
|
SBI_SCRATCH_NO_BOOT_PRINTS = (1 << 0),
|
2019-08-08 14:40:22 +08:00
|
|
|
/** Enable runtime debug prints */
|
|
|
|
SBI_SCRATCH_DEBUG_PRINTS = (1 << 1),
|
2019-03-27 22:58:49 +08:00
|
|
|
};
|
|
|
|
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Get pointer to sbi_scratch for current HART */
|
2019-04-11 08:41:52 +08:00
|
|
|
#define sbi_scratch_thishart_ptr() \
|
|
|
|
((struct sbi_scratch *)csr_read(CSR_MSCRATCH))
|
2018-12-11 21:54:06 +08:00
|
|
|
|
2019-01-14 16:30:32 +08:00
|
|
|
/** Get Arg1 of next booting stage for current HART */
|
2019-04-11 08:41:52 +08:00
|
|
|
#define sbi_scratch_thishart_arg1_ptr() \
|
|
|
|
((void *)(sbi_scratch_thishart_ptr()->next_arg1))
|
2018-12-11 21:54:06 +08:00
|
|
|
|
2020-10-01 18:27:47 +08:00
|
|
|
/** Initialize scratch table and allocator */
|
2020-03-14 12:27:45 +08:00
|
|
|
int sbi_scratch_init(struct sbi_scratch *scratch);
|
|
|
|
|
2020-03-09 11:52:41 +08:00
|
|
|
/**
|
|
|
|
* Allocate from extra space in sbi_scratch
|
2019-05-21 14:21:01 +08:00
|
|
|
*
|
|
|
|
* @return zero on failure and non-zero (>= SBI_SCRATCH_EXTRA_SPACE_OFFSET)
|
|
|
|
* on success
|
|
|
|
*/
|
2021-05-30 03:54:29 +08:00
|
|
|
unsigned long sbi_scratch_alloc_offset(unsigned long size);
|
2019-05-21 14:21:01 +08:00
|
|
|
|
|
|
|
/** Free-up extra space in sbi_scratch */
|
|
|
|
void sbi_scratch_free_offset(unsigned long offset);
|
2019-03-09 03:22:22 +08:00
|
|
|
|
2019-05-21 14:21:01 +08:00
|
|
|
/** Get pointer from offset in sbi_scratch */
|
2022-01-19 17:20:17 +08:00
|
|
|
#define sbi_scratch_offset_ptr(scratch, offset) (void *)((char *)(scratch) + (offset))
|
2019-04-02 08:07:54 +08:00
|
|
|
|
2019-05-21 14:21:01 +08:00
|
|
|
/** Get pointer from offset in sbi_scratch for current HART */
|
|
|
|
#define sbi_scratch_thishart_offset_ptr(offset) \
|
2022-01-19 17:20:17 +08:00
|
|
|
(void *)((char *)sbi_scratch_thishart_ptr() + (offset))
|
2019-03-10 04:57:20 +08:00
|
|
|
|
2020-03-14 12:27:45 +08:00
|
|
|
/** HART id to scratch table */
|
|
|
|
extern struct sbi_scratch *hartid_to_scratch_table[];
|
2020-03-11 21:38:08 +08:00
|
|
|
|
|
|
|
/** Get sbi_scratch from HART id */
|
2020-03-14 16:50:22 +08:00
|
|
|
#define sbi_hartid_to_scratch(__hartid) \
|
2020-03-14 12:27:45 +08:00
|
|
|
hartid_to_scratch_table[__hartid]
|
2020-03-11 21:38:08 +08:00
|
|
|
|
2020-03-26 21:05:38 +08:00
|
|
|
/** Last HART id having a sbi_scratch pointer */
|
|
|
|
extern u32 last_hartid_having_scratch;
|
|
|
|
|
|
|
|
/** Get last HART id having a sbi_scratch pointer */
|
|
|
|
#define sbi_scratch_last_hartid() last_hartid_having_scratch
|
|
|
|
|
2018-12-11 21:54:06 +08:00
|
|
|
#endif
|
2018-12-31 13:49:20 +08:00
|
|
|
|
|
|
|
#endif
|