Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f31163c8f | ||
|
|
ea9e72801c | ||
|
|
796206b5ac | ||
|
|
1c56f6babc | ||
|
|
62ba2d48dd | ||
|
|
7b94a32be2 | ||
|
|
9e7b8db24d |
2
Kconfig
2
Kconfig
@@ -551,7 +551,7 @@ config SYS_LOAD_ADDR
|
|||||||
default 0x12000000 if ARCH_MX6 && !(MX6SL || MX6SLL || MX6SX || MX6UL || MX6ULL)
|
default 0x12000000 if ARCH_MX6 && !(MX6SL || MX6SLL || MX6SX || MX6UL || MX6ULL)
|
||||||
default 0x80800000 if ARCH_MX7
|
default 0x80800000 if ARCH_MX7
|
||||||
default 0x90000000 if FSL_LSCH2 || FSL_LSCH3
|
default 0x90000000 if FSL_LSCH2 || FSL_LSCH3
|
||||||
default 0x02000000 if ARCH_EFI
|
default 0 if ARCH_EFI
|
||||||
default 0x0 if ARCH_SC5XX
|
default 0x0 if ARCH_SC5XX
|
||||||
help
|
help
|
||||||
Address in memory to use as the default safe load address.
|
Address in memory to use as the default safe load address.
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ choice
|
|||||||
config TARGET_VEXPRESS64_BASE_FVP
|
config TARGET_VEXPRESS64_BASE_FVP
|
||||||
bool "Support Versatile Express ARMv8a FVP BASE model"
|
bool "Support Versatile Express ARMv8a FVP BASE model"
|
||||||
select VEXPRESS64_BASE_MODEL
|
select VEXPRESS64_BASE_MODEL
|
||||||
imply OF_HAS_PRIOR_STAGE
|
imply OF_HAS_PRIOR_STAGE if !BLOBLIST
|
||||||
|
|
||||||
config TARGET_VEXPRESS64_BASER_FVP
|
config TARGET_VEXPRESS64_BASER_FVP
|
||||||
bool "Support Versatile Express ARMv8r64 FVP BASE model"
|
bool "Support Versatile Express ARMv8r64 FVP BASE model"
|
||||||
|
|||||||
@@ -3,5 +3,8 @@
|
|||||||
# (C) Copyright 2000-2004
|
# (C) Copyright 2000-2004
|
||||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||||
|
|
||||||
obj-y := vexpress64.o lowlevel_init.o
|
obj-y := vexpress64.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_OF_HAS_PRIOR_STAGE) += lowlevel_init.o
|
||||||
|
|
||||||
obj-$(CONFIG_TARGET_VEXPRESS64_JUNO) += pcie.o
|
obj-$(CONFIG_TARGET_VEXPRESS64_JUNO) += pcie.o
|
||||||
|
|||||||
@@ -100,7 +100,9 @@ int dram_init_banksize(void)
|
|||||||
* Push the variable into the .data section so that it
|
* Push the variable into the .data section so that it
|
||||||
* does not get cleared later.
|
* does not get cleared later.
|
||||||
*/
|
*/
|
||||||
|
#ifdef CONFIG_OF_HAS_PRIOR_STAGE
|
||||||
unsigned long __section(".data") prior_stage_fdt_address[2];
|
unsigned long __section(".data") prior_stage_fdt_address[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_OF_BOARD
|
#ifdef CONFIG_OF_BOARD
|
||||||
|
|
||||||
@@ -151,6 +153,7 @@ static phys_addr_t find_dtb_in_nor_flash(const char *partname)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF_HAS_PRIOR_STAGE
|
||||||
/*
|
/*
|
||||||
* Filter for a valid DTB, as TF-A happens to provide a pointer to some
|
* Filter for a valid DTB, as TF-A happens to provide a pointer to some
|
||||||
* data structure using the DTB format, which we cannot use.
|
* data structure using the DTB format, which we cannot use.
|
||||||
@@ -201,6 +204,7 @@ int board_fdt_blob_setup(void **fdtp)
|
|||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Actual reset is done via PSCI. */
|
/* Actual reset is done via PSCI. */
|
||||||
void reset_cpu(void)
|
void reset_cpu(void)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ config TARGET_EFI_X86_APP32
|
|||||||
help
|
help
|
||||||
This target is used for running U-Boot on top of EFI. In
|
This target is used for running U-Boot on top of EFI. In
|
||||||
this case EFI does the early initialisation, and U-Boot
|
this case EFI does the early initialisation, and U-Boot
|
||||||
takes over once the RAM, video and CPU are fully running.
|
starts once the RAM, video and CPU are fully running.
|
||||||
U-Boot is loaded as an application from EFI.
|
U-Boot is loaded as an application from EFI.
|
||||||
|
|
||||||
config TARGET_EFI_X86_APP64
|
config TARGET_EFI_X86_APP64
|
||||||
@@ -27,7 +27,7 @@ config TARGET_EFI_X86_APP64
|
|||||||
help
|
help
|
||||||
This target is used for running U-Boot on top of EFI in 64-bit mode.
|
This target is used for running U-Boot on top of EFI in 64-bit mode.
|
||||||
In this case EFI does the early initialisation, and U-Boot
|
In this case EFI does the early initialisation, and U-Boot
|
||||||
takes over once the RAM, video and CPU are fully running.
|
starts once the RAM, video and CPU are fully running.
|
||||||
U-Boot is loaded as an application from EFI.
|
U-Boot is loaded as an application from EFI.
|
||||||
|
|
||||||
config TARGET_EFI_X86_PAYLOAD
|
config TARGET_EFI_X86_PAYLOAD
|
||||||
@@ -59,7 +59,7 @@ config TARGET_EFI_ARM_APP64
|
|||||||
help
|
help
|
||||||
This target is used for running U-Boot on top of EFI in 64-bit mode.
|
This target is used for running U-Boot on top of EFI in 64-bit mode.
|
||||||
In this case EFI does the early initialisation, and U-Boot
|
In this case EFI does the early initialisation, and U-Boot
|
||||||
takes over once the RAM, video and CPU are fully running.
|
starts once the RAM, video and CPU are fully running.
|
||||||
U-Boot is loaded as an application from EFI.
|
U-Boot is loaded as an application from EFI.
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|||||||
@@ -1,10 +1,3 @@
|
|||||||
EFI-ARM_APP32 BOARD
|
|
||||||
M: Simon Glass <sjg@chromium.org>
|
|
||||||
S: Maintained
|
|
||||||
F: board/efi/Kconfig
|
|
||||||
F: board/efi/efi-arm_app/
|
|
||||||
F: configs/efi-arm_app32_defconfig
|
|
||||||
|
|
||||||
EFI-ARM_APP64 BOARD
|
EFI-ARM_APP64 BOARD
|
||||||
M: Simon Glass <sjg@chromium.org>
|
M: Simon Glass <sjg@chromium.org>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|||||||
33
boot/bootm.c
33
boot/bootm.c
@@ -1185,6 +1185,39 @@ int bootm_run(struct bootm_info *bmi)
|
|||||||
|
|
||||||
int bootz_run(struct bootm_info *bmi)
|
int bootz_run(struct bootm_info *bmi)
|
||||||
{
|
{
|
||||||
|
struct bootm_headers *images = bmi->images;
|
||||||
|
ulong zi_start, zi_end;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bootm_run_states(bmi, BOOTM_STATE_START);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
images->ep = bmi->addr_img ? hextoul(bmi->addr_img, NULL) :
|
||||||
|
image_load_addr;
|
||||||
|
|
||||||
|
ret = bootz_setup(images->ep, &zi_start, &zi_end);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
lmb_reserve(images->ep, zi_end - zi_start);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
|
||||||
|
* have a header that provide this informaiton.
|
||||||
|
*/
|
||||||
|
if (bootm_find_images(images->ep, bmi->conf_ramdisk, bmi->conf_fdt,
|
||||||
|
images->ep, zi_end - zi_start))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are doing the BOOTM_STATE_LOADOS state ourselves, so must
|
||||||
|
* disable interrupts ourselves
|
||||||
|
*/
|
||||||
|
bootm_disable_interrupts();
|
||||||
|
|
||||||
|
images->os.os = IH_OS_LINUX;
|
||||||
|
|
||||||
return boot_run(bmi, "bootz", 0);
|
return boot_run(bmi, "bootz", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
65
cmd/bootz.c
65
cmd/bootz.c
@@ -20,56 +20,6 @@ int __weak bootz_setup(ulong image, ulong *start, ulong *end)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* zImage booting support
|
|
||||||
*/
|
|
||||||
static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc,
|
|
||||||
char *const argv[], struct bootm_headers *images)
|
|
||||||
{
|
|
||||||
ulong zi_start, zi_end;
|
|
||||||
struct bootm_info bmi;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bootm_init(&bmi);
|
|
||||||
if (argc)
|
|
||||||
bmi.addr_img = argv[0];
|
|
||||||
if (argc > 1)
|
|
||||||
bmi.conf_ramdisk = argv[1];
|
|
||||||
if (argc > 2)
|
|
||||||
bmi.conf_fdt = argv[2];
|
|
||||||
/* do not set up argc and argv[] since nothing uses them */
|
|
||||||
|
|
||||||
ret = bootm_run_states(&bmi, BOOTM_STATE_START);
|
|
||||||
|
|
||||||
/* Setup Linux kernel zImage entry point */
|
|
||||||
if (!argc) {
|
|
||||||
images->ep = image_load_addr;
|
|
||||||
debug("* kernel: default image load address = 0x%08lx\n",
|
|
||||||
image_load_addr);
|
|
||||||
} else {
|
|
||||||
images->ep = hextoul(argv[0], NULL);
|
|
||||||
debug("* kernel: cmdline image address = 0x%08lx\n",
|
|
||||||
images->ep);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bootz_setup(images->ep, &zi_start, &zi_end);
|
|
||||||
if (ret != 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
lmb_reserve(images->ep, zi_end - zi_start);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
|
|
||||||
* have a header that provide this informaiton.
|
|
||||||
*/
|
|
||||||
if (bootm_find_images(image_load_addr, cmd_arg1(argc, argv),
|
|
||||||
cmd_arg2(argc, argv), images->ep,
|
|
||||||
zi_end - zi_start))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int do_bootz(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
int do_bootz(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||||
{
|
{
|
||||||
struct bootm_info bmi;
|
struct bootm_info bmi;
|
||||||
@@ -78,17 +28,6 @@ int do_bootz(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
|||||||
/* Consume 'bootz' */
|
/* Consume 'bootz' */
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
|
|
||||||
if (bootz_start(cmdtp, flag, argc, argv, &images))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We are doing the BOOTM_STATE_LOADOS state ourselves, so must
|
|
||||||
* disable interrupts ourselves
|
|
||||||
*/
|
|
||||||
bootm_disable_interrupts();
|
|
||||||
|
|
||||||
images.os.os = IH_OS_LINUX;
|
|
||||||
|
|
||||||
bootm_init(&bmi);
|
bootm_init(&bmi);
|
||||||
if (argc)
|
if (argc)
|
||||||
bmi.addr_img = argv[0];
|
bmi.addr_img = argv[0];
|
||||||
@@ -99,8 +38,10 @@ int do_bootz(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
|||||||
bmi.cmd_name = "bootz";
|
bmi.cmd_name = "bootz";
|
||||||
|
|
||||||
ret = bootz_run(&bmi);
|
ret = bootz_run(&bmi);
|
||||||
|
if (ret)
|
||||||
|
return CMD_RET_FAILURE;
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
U_BOOT_LONGHELP(bootz,
|
U_BOOT_LONGHELP(bootz,
|
||||||
|
|||||||
@@ -1055,8 +1055,8 @@ choice
|
|||||||
config BLOBLIST_FIXED
|
config BLOBLIST_FIXED
|
||||||
bool "Place bloblist at a fixed address in memory"
|
bool "Place bloblist at a fixed address in memory"
|
||||||
help
|
help
|
||||||
Select this to used a fixed memory address for the bloblist. If the
|
Select this to use a fixed memory address for the bloblist. If the
|
||||||
bloblist exists at this address from a previous phase, it used as is.
|
bloblist exists at this address from a previous phase, it is used as is.
|
||||||
If not it is created at this address in U-Boot.
|
If not it is created at this address in U-Boot.
|
||||||
|
|
||||||
config BLOBLIST_ALLOC
|
config BLOBLIST_ALLOC
|
||||||
@@ -1066,6 +1066,12 @@ config BLOBLIST_ALLOC
|
|||||||
specify a fixed address on systems where this is unknown or can
|
specify a fixed address on systems where this is unknown or can
|
||||||
change at runtime.
|
change at runtime.
|
||||||
|
|
||||||
|
config BLOBLIST_PASSAGE
|
||||||
|
bool "Use bloblist in-place"
|
||||||
|
help
|
||||||
|
Use a bloblist in the incoming standard passage. The size is detected
|
||||||
|
automatically so CONFIG_BLOBLIST_SIZE can be 0.
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config BLOBLIST_ADDR
|
config BLOBLIST_ADDR
|
||||||
@@ -1080,17 +1086,17 @@ config BLOBLIST_ADDR
|
|||||||
|
|
||||||
config BLOBLIST_SIZE
|
config BLOBLIST_SIZE
|
||||||
hex "Size of bloblist"
|
hex "Size of bloblist"
|
||||||
|
default 0x0 if BLOBLIST_PASSAGE
|
||||||
default 0x400
|
default 0x400
|
||||||
help
|
help
|
||||||
Sets the size of the bloblist in bytes. This must include all
|
Sets the size of the bloblist in bytes. This must include all
|
||||||
overhead (alignment, bloblist header, record header). The bloblist
|
overhead (alignment, bloblist header, record header). The bloblist
|
||||||
is set up in the first part of U-Boot to run (TPL, SPL or U-Boot
|
is set up in the first part of U-Boot to run (TPL, SPL or U-Boot
|
||||||
proper), and this sane bloblist is used for subsequent phases.
|
proper), and this same bloblist is used for subsequent phases.
|
||||||
|
|
||||||
config BLOBLIST_SIZE_RELOC
|
config BLOBLIST_SIZE_RELOC
|
||||||
hex "Size of bloblist after relocation"
|
hex "Size of bloblist after relocation"
|
||||||
default BLOBLIST_SIZE if BLOBLIST_FIXED || BLOBLIST_ALLOC
|
default BLOBLIST_SIZE if BLOBLIST_FIXED || BLOBLIST_ALLOC
|
||||||
default 0x0 if BLOBLIST_PASSAGE
|
|
||||||
default 0x20000 if (ARM && EFI_LOADER && GENERATE_ACPI_TABLE)
|
default 0x20000 if (ARM && EFI_LOADER && GENERATE_ACPI_TABLE)
|
||||||
help
|
help
|
||||||
Sets the size of the bloblist in bytes after relocation. Since U-Boot
|
Sets the size of the bloblist in bytes after relocation. Since U-Boot
|
||||||
|
|||||||
@@ -489,6 +489,9 @@ int bloblist_reloc(void *to, uint to_size)
|
|||||||
{
|
{
|
||||||
struct bloblist_hdr *hdr;
|
struct bloblist_hdr *hdr;
|
||||||
|
|
||||||
|
if (!to_size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (to_size < gd->bloblist->total_size)
|
if (to_size < gd->bloblist->total_size)
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
@@ -519,13 +522,6 @@ int bloblist_init(void)
|
|||||||
* at a fixed address.
|
* at a fixed address.
|
||||||
*/
|
*/
|
||||||
bool from_addr = fixed && !xpl_is_first_phase();
|
bool from_addr = fixed && !xpl_is_first_phase();
|
||||||
/*
|
|
||||||
* If U-Boot is in the first phase that an arch custom routine should
|
|
||||||
* install the bloblist passed from previous loader to this fixed
|
|
||||||
* address.
|
|
||||||
*/
|
|
||||||
bool from_boot_arg = fixed && xpl_is_first_phase();
|
|
||||||
|
|
||||||
if (xpl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST))
|
if (xpl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST))
|
||||||
from_addr = false;
|
from_addr = false;
|
||||||
if (fixed)
|
if (fixed)
|
||||||
@@ -533,7 +529,13 @@ int bloblist_init(void)
|
|||||||
CONFIG_BLOBLIST_ADDR);
|
CONFIG_BLOBLIST_ADDR);
|
||||||
size = CONFIG_BLOBLIST_SIZE;
|
size = CONFIG_BLOBLIST_SIZE;
|
||||||
|
|
||||||
if (from_boot_arg)
|
|
||||||
|
/*
|
||||||
|
* If the current boot stage is the first phase of U-Boot, then an
|
||||||
|
* architecture-specific routine should be used to handle the bloblist
|
||||||
|
* passed from the previous boot loader
|
||||||
|
*/
|
||||||
|
if (xpl_is_first_phase() && !IS_ENABLED(CONFIG_BLOBLIST_ALLOC))
|
||||||
ret = xferlist_from_boot_arg(addr, size);
|
ret = xferlist_from_boot_arg(addr, size);
|
||||||
else if (from_addr)
|
else if (from_addr)
|
||||||
ret = bloblist_check(addr, size);
|
ret = bloblist_check(addr, size);
|
||||||
|
|||||||
5
configs/vexpress_fvp_bloblist_defconfig
Normal file
5
configs/vexpress_fvp_bloblist_defconfig
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#include <configs/vexpress_fvp_defconfig>
|
||||||
|
|
||||||
|
CONFIG_BLOBLIST=y
|
||||||
|
CONFIG_BLOBLIST_PASSAGE=y
|
||||||
|
CONFIG_BLOBLIST_SIZE_RELOC=0x10000
|
||||||
@@ -43,6 +43,22 @@ Juno is an Arm development board with the following features:
|
|||||||
|
|
||||||
More details can be found in the board documentation [3]_.
|
More details can be found in the board documentation [3]_.
|
||||||
|
|
||||||
|
Bloblist Support
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The ``vexpress_fvp_bloblist_defconfig`` configures U-Boot to be compiled for
|
||||||
|
Vexpress64 with Bloblist as the primary method for information handoff between
|
||||||
|
boot stages. U-Boot offers three methods to set up a bloblist: using a
|
||||||
|
predefined bloblist at a specified address, dynamically allocating memory for a
|
||||||
|
bloblist, or utilizing a standard passage-provided bloblist with automatic size
|
||||||
|
detection.
|
||||||
|
|
||||||
|
By default, ``vexpress_fvp_bloblist_defconfig`` uses the standard passage method
|
||||||
|
(CONFIG_BLOBLIST_PASSAGE) because TF-A provides a Transfer List in non-secure
|
||||||
|
memory that U-Boot can utilise. This Bloblist, which is referred to as a Transfer List in
|
||||||
|
TF-A, contains all necessary data for the handoff process, including DT and ACPI
|
||||||
|
tables.
|
||||||
|
|
||||||
References
|
References
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
|||||||
@@ -475,7 +475,7 @@ int bloblist_init(void);
|
|||||||
/**
|
/**
|
||||||
* bloblist_maybe_init() - Init the bloblist system if not already done
|
* bloblist_maybe_init() - Init the bloblist system if not already done
|
||||||
*
|
*
|
||||||
* Calls bloblist_init() if the GD_FLG_BLOBLIST_READY flag is not et
|
* Calls bloblist_init() if the GD_FLG_BLOBLIST_READY flag is not set
|
||||||
*
|
*
|
||||||
* Return: 0 if OK, -ve on error
|
* Return: 0 if OK, -ve on error
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -169,12 +169,14 @@
|
|||||||
" if load hostfs - ${kernel_addr_r} ${kernel_name}; then" \
|
" if load hostfs - ${kernel_addr_r} ${kernel_name}; then" \
|
||||||
" setenv fdt_high 0xffffffffffffffff;" \
|
" setenv fdt_high 0xffffffffffffffff;" \
|
||||||
" setenv initrd_high 0xffffffffffffffff;" \
|
" setenv initrd_high 0xffffffffffffffff;" \
|
||||||
" load hostfs - ${fdt_addr_r} ${fdtfile};" \
|
" if test -n load hostfs - ${fdt_addr_r} ${fdtfile}; then" \
|
||||||
|
" fdt move $fdtcontroladdr $fdt_addr_r;" \
|
||||||
|
" fi;" \
|
||||||
" load hostfs - ${ramdisk_addr_r} ${ramdisk_name};" \
|
" load hostfs - ${ramdisk_addr_r} ${ramdisk_name};" \
|
||||||
" fdt addr ${fdt_addr_r};" \
|
" fdt addr ${fdt_addr_r};" \
|
||||||
" fdt resize;" \
|
" fdt resize;" \
|
||||||
" fdt chosen ${ramdisk_addr_r} ${filesize};" \
|
" fdt chosen ${ramdisk_addr_r} ${filesize};" \
|
||||||
" booti $kernel_addr_r - $fdt_addr_r;" \
|
" booti $kernel_addr_r - ${fdt_addr_r};" \
|
||||||
" fi;" \
|
" fi;" \
|
||||||
"fi\0"
|
"fi\0"
|
||||||
#define BOOTENV_DEV_NAME_SMH(devtypeu, devtypel, instance) "smh "
|
#define BOOTENV_DEV_NAME_SMH(devtypeu, devtypel, instance) "smh "
|
||||||
|
|||||||
Reference in New Issue
Block a user