Merge branch 'master' of git://www.denx.de/git/u-boot-x86
This commit is contained in:
commit
e57d9d15ee
6
Makefile
6
Makefile
@ -231,8 +231,8 @@ endif
|
||||
|
||||
OBJS = $(CPUDIR)/start.o
|
||||
ifeq ($(CPU),x86)
|
||||
OBJS += $(CPUDIR)/start16.o
|
||||
OBJS += $(CPUDIR)/resetvec.o
|
||||
RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/start16.o
|
||||
RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/resetvec.o
|
||||
endif
|
||||
ifeq ($(CPU),ppc4xx)
|
||||
OBJS += $(CPUDIR)/resetvec.o
|
||||
@ -241,7 +241,7 @@ ifeq ($(CPU),mpc85xx)
|
||||
OBJS += $(CPUDIR)/resetvec.o
|
||||
endif
|
||||
|
||||
OBJS := $(addprefix $(obj),$(OBJS))
|
||||
OBJS := $(addprefix $(obj),$(OBJS) $(RESET_OBJS-))
|
||||
|
||||
HAVE_VENDOR_COMMON_LIB = $(if $(wildcard board/$(VENDOR)/common/Makefile),y,n)
|
||||
|
||||
|
4
README
4
README
@ -3664,6 +3664,10 @@ Low Level (hardware related) configuration options:
|
||||
be used if available. These functions may be faster under some
|
||||
conditions but may increase the binary size.
|
||||
|
||||
- CONFIG_X86_NO_RESET_VECTOR
|
||||
If defined, the x86 reset vector code is excluded. You will need
|
||||
to do this when U-Boot is running from Coreboot.
|
||||
|
||||
Freescale QE/FMAN Firmware Support:
|
||||
-----------------------------------
|
||||
|
||||
|
@ -28,12 +28,13 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(CPU).o
|
||||
|
||||
START = start.o start16.o resetvec.o
|
||||
START-y = start.o
|
||||
RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += resetvec.o start16.o
|
||||
COBJS = interrupts.o cpu.o
|
||||
|
||||
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
START := $(addprefix $(obj),$(START))
|
||||
START := $(addprefix $(obj),$(START-y) $(RESET_OBJS-))
|
||||
|
||||
all: $(obj).depend $(START) $(LIB)
|
||||
|
||||
|
@ -33,10 +33,12 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB := $(obj)lib$(SOC).o
|
||||
|
||||
COBJS-$(CONFIG_SYS_COREBOOT) += coreboot.o
|
||||
COBJS-$(CONFIG_SYS_COREBOOT) += tables.o
|
||||
COBJS-$(CONFIG_SYS_COREBOOT) += ipchecksum.o
|
||||
COBJS-$(CONFIG_SYS_COREBOOT) += sdram.o
|
||||
COBJS-$(CONFIG_SYS_COREBOOT) += sysinfo.o
|
||||
COBJS-$(CONFIG_PCI) += pci.o
|
||||
|
||||
SOBJS-$(CONFIG_SYS_COREBOOT) += coreboot_car.o
|
||||
|
||||
|
@ -25,6 +25,41 @@
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <pci.h>
|
||||
#include <asm/pci.h>
|
||||
|
||||
static struct pci_controller coreboot_hose;
|
||||
|
||||
static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev,
|
||||
struct pci_config_table *table)
|
||||
{
|
||||
u8 secondary;
|
||||
hose->read_byte(hose, dev, PCI_SECONDARY_BUS, &secondary);
|
||||
hose->last_busno = max(hose->last_busno, secondary);
|
||||
pci_hose_scan_bus(hose, secondary);
|
||||
}
|
||||
|
||||
static struct pci_config_table pci_coreboot_config_table[] = {
|
||||
/* vendor, device, class, bus, dev, func */
|
||||
{ PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI,
|
||||
PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, &config_pci_bridge },
|
||||
{}
|
||||
};
|
||||
|
||||
void pci_init_board(void)
|
||||
{
|
||||
coreboot_hose.config_table = pci_coreboot_config_table;
|
||||
coreboot_hose.first_busno = 0;
|
||||
coreboot_hose.last_busno = 0;
|
||||
|
||||
pci_set_region(coreboot_hose.regions + 0, 0x0, 0x0, 0xffffffff,
|
||||
PCI_REGION_MEM);
|
||||
coreboot_hose.region_count = 1;
|
||||
|
||||
pci_setup_type1(&coreboot_hose);
|
||||
|
||||
pci_register_hose(&coreboot_hose);
|
||||
|
||||
pci_hose_scan(&coreboot_hose);
|
||||
}
|
@ -90,12 +90,6 @@ static void load_gdt(const u64 *boot_gdt, u16 num_entries)
|
||||
asm volatile("lgdtl %0\n" : : "m" (gdt));
|
||||
}
|
||||
|
||||
void init_gd(gd_t *id, u64 *gdt_addr)
|
||||
{
|
||||
id->gd_addr = (ulong)id;
|
||||
setup_gdt(id, gdt_addr);
|
||||
}
|
||||
|
||||
void setup_gdt(gd_t *id, u64 *gdt_addr)
|
||||
{
|
||||
/* CS: code, read/execute, 4 GB, base 0 */
|
||||
|
@ -83,13 +83,33 @@ car_init_ret:
|
||||
* or fully initialised SDRAM - we really don't care which)
|
||||
* starting at CONFIG_SYS_CAR_ADDR to be used as a temporary stack
|
||||
*/
|
||||
movl $CONFIG_SYS_INIT_SP_ADDR, %esp
|
||||
|
||||
/* Initialise the Global Data Pointer */
|
||||
movl $CONFIG_SYS_INIT_GD_ADDR, %eax
|
||||
movl %eax, %edx
|
||||
addl $GENERATED_GBL_DATA_SIZE, %edx
|
||||
call init_gd;
|
||||
/* Stack grows down from top of CAR */
|
||||
movl $(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE), %esp
|
||||
|
||||
/* Reserve space on stack for global data */
|
||||
subl $GENERATED_GBL_DATA_SIZE, %esp
|
||||
|
||||
/* Align global data to 16-byte boundary */
|
||||
andl $0xfffffff0, %esp
|
||||
|
||||
/* Setup first parameter to setup_gdt */
|
||||
movl %esp, %eax
|
||||
|
||||
/* Reserve space for global descriptor table */
|
||||
subl $X86_GDT_SIZE, %esp
|
||||
|
||||
/* Align temporary global descriptor table to 16-byte boundary */
|
||||
andl $0xfffffff0, %esp
|
||||
|
||||
/* Set second parameter to setup_gdt */
|
||||
movl %esp, %edx
|
||||
|
||||
/* gd->gd_addr = gd (Required to allow gd->xyz to work) */
|
||||
movl %eax, (%eax)
|
||||
|
||||
/* Setup global descriptor table so gd->xyz works */
|
||||
call setup_gdt
|
||||
|
||||
/* Set parameter to board_init_f() to boot flags */
|
||||
xorl %eax, %eax
|
||||
@ -113,9 +133,42 @@ board_init_f_r_trampoline:
|
||||
* %eax = Address of top of new stack
|
||||
*/
|
||||
|
||||
/* Setup stack in RAM */
|
||||
/* Stack grows down from top of SDRAM */
|
||||
movl %eax, %esp
|
||||
|
||||
/* Reserve space on stack for global data */
|
||||
subl $GENERATED_GBL_DATA_SIZE, %esp
|
||||
|
||||
/* Align global data to 16-byte boundary */
|
||||
andl $0xfffffff0, %esp
|
||||
|
||||
/* Setup first parameter to memcpy (and setup_gdt) */
|
||||
movl %esp, %eax
|
||||
|
||||
/* Setup second parameter to memcpy */
|
||||
fs movl 0, %edx
|
||||
|
||||
/* Set third parameter to memcpy */
|
||||
movl $GENERATED_GBL_DATA_SIZE, %ecx
|
||||
|
||||
/* Copy global data from CAR to SDRAM stack */
|
||||
call memcpy
|
||||
|
||||
/* Reserve space for global descriptor table */
|
||||
subl $X86_GDT_SIZE, %esp
|
||||
|
||||
/* Align global descriptor table to 16-byte boundary */
|
||||
andl $0xfffffff0, %esp
|
||||
|
||||
/* Set second parameter to setup_gdt */
|
||||
movl %esp, %edx
|
||||
|
||||
/* gd->gd_addr = gd (Required to allow gd->xyz to work) */
|
||||
movl %eax, (%eax)
|
||||
|
||||
/* Setup global descriptor table so gd->xyz works */
|
||||
call setup_gdt
|
||||
|
||||
/* Re-enter U-Boot by calling board_init_f_r */
|
||||
call board_init_f_r
|
||||
|
||||
|
@ -86,6 +86,8 @@ SECTIONS
|
||||
__bios_start = LOADADDR(.bios);
|
||||
__bios_size = SIZEOF(.bios);
|
||||
|
||||
#ifndef CONFIG_X86_NO_RESET_VECTOR
|
||||
|
||||
/*
|
||||
* The following expressions place the 16-bit Real-Mode code and
|
||||
* Reset Vector at the end of the Flash ROM
|
||||
@ -95,4 +97,5 @@ SECTIONS
|
||||
|
||||
. = RESET_VEC_LOC;
|
||||
.resetvec : AT (CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE + RESET_VEC_LOC)) { KEEP(*(.resetvec)); }
|
||||
#endif
|
||||
}
|
||||
|
@ -351,6 +351,11 @@ static __inline__ int ffs(int x)
|
||||
}
|
||||
#define PLATFORM_FFS
|
||||
|
||||
static inline int __ilog2(unsigned int x)
|
||||
{
|
||||
return generic_fls(x) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* hweightN - returns the hamming weight of a N-bit word
|
||||
* @x: the word to weigh
|
||||
|
@ -33,9 +33,13 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
typedef struct global_data {
|
||||
#include <asm/u-boot.h>
|
||||
|
||||
typedef struct global_data gd_t;
|
||||
|
||||
struct global_data {
|
||||
/* NOTE: gd_addr MUST be first member of struct global_data! */
|
||||
unsigned long gd_addr; /* Location of Global Data */
|
||||
gd_t *gd_addr; /* Location of Global Data */
|
||||
bd_t *bd;
|
||||
unsigned long flags;
|
||||
unsigned int baudrate;
|
||||
@ -52,12 +56,11 @@ typedef struct global_data {
|
||||
unsigned long relocaddr; /* Start address of U-Boot in RAM */
|
||||
unsigned long start_addr_sp; /* start_addr_stackpointer */
|
||||
unsigned long gdt_addr; /* Location of GDT */
|
||||
unsigned long new_gd_addr; /* New location of Global Data */
|
||||
phys_size_t ram_size; /* RAM size */
|
||||
unsigned long reset_status; /* reset status register at boot */
|
||||
void **jt; /* jump table */
|
||||
char env_buf[32]; /* buffer for getenv() before reloc. */
|
||||
} gd_t;
|
||||
};
|
||||
|
||||
static inline gd_t *get_fs_gd_ptr(void)
|
||||
{
|
||||
|
@ -29,7 +29,6 @@ int display_dram_config(void);
|
||||
int init_baudrate_f(void);
|
||||
int calculate_relocation_address(void);
|
||||
|
||||
int copy_gd_to_ram_f_r(void);
|
||||
int init_cache_f_r(void);
|
||||
|
||||
int set_reloc_flag_r(void);
|
||||
|
@ -234,4 +234,12 @@ static inline phys_addr_t virt_to_phys(void * vaddr)
|
||||
return (phys_addr_t)(vaddr);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: The kernel offers some more advanced versions of barriers, it might
|
||||
* have some advantages to use them instead of the simple one here.
|
||||
*/
|
||||
#define dmb() __asm__ __volatile__ ("" : : : "memory")
|
||||
#define __iormb() dmb()
|
||||
#define __iowmb() dmb()
|
||||
|
||||
#endif
|
||||
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
#ifndef _PCI_I386_H_
|
||||
#define _PCI_I386_H_ 1
|
||||
#define _PCI_I386_H_
|
||||
|
||||
#define DEFINE_PCI_DEVICE_TABLE(_table) \
|
||||
const struct pci_device_id _table[]
|
||||
|
@ -41,6 +41,7 @@ enum {
|
||||
#else
|
||||
/* NOTE: If the above enum is modified, this define must be checked */
|
||||
#define X86_GDT_ENTRY_32BIT_DS 3
|
||||
#define X86_GDT_NUM_ENTRIES 7
|
||||
#endif
|
||||
|
||||
#define X86_GDT_SIZE (X86_GDT_NUM_ENTRIES * X86_GDT_ENTRY_SIZE)
|
||||
|
@ -36,6 +36,9 @@
|
||||
#ifndef _U_BOOT_H_
|
||||
#define _U_BOOT_H_ 1
|
||||
|
||||
#include <config.h>
|
||||
#include <compiler.h>
|
||||
|
||||
typedef struct bd_info {
|
||||
unsigned long bi_memstart; /* start of DRAM memory */
|
||||
phys_size_t bi_memsize; /* size of DRAM memory in bytes */
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <stdio_dev.h>
|
||||
#include <asm/u-boot-x86.h>
|
||||
#include <asm/relocate.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
#include <asm/init_helpers.h>
|
||||
#include <asm/init_wrappers.h>
|
||||
@ -121,7 +122,6 @@ init_fnc_t *init_sequence_f[] = {
|
||||
* initialise the CPU caches (to speed up the relocation process)
|
||||
*/
|
||||
init_fnc_t *init_sequence_f_r[] = {
|
||||
copy_gd_to_ram_f_r,
|
||||
init_cache_f_r,
|
||||
copy_uboot_to_ram,
|
||||
clear_bss,
|
||||
@ -164,9 +164,6 @@ init_fnc_t *init_sequence_r[] = {
|
||||
#ifdef CONFIG_MISC_INIT_R
|
||||
misc_init_r,
|
||||
#endif
|
||||
#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE)
|
||||
pci_init_r,
|
||||
#endif
|
||||
#if defined(CONFIG_CMD_KGDB)
|
||||
kgdb_init_r,
|
||||
#endif
|
||||
|
@ -83,18 +83,8 @@ int calculate_relocation_address(void)
|
||||
* requirements
|
||||
*/
|
||||
|
||||
/* Global Data is at top of available memory */
|
||||
/* Stack is at top of available memory */
|
||||
dest_addr = gd->ram_size;
|
||||
dest_addr -= GENERATED_GBL_DATA_SIZE;
|
||||
dest_addr &= ~15;
|
||||
gd->new_gd_addr = dest_addr;
|
||||
|
||||
/* GDT is below Global Data */
|
||||
dest_addr -= X86_GDT_SIZE;
|
||||
dest_addr &= ~15;
|
||||
gd->gdt_addr = dest_addr;
|
||||
|
||||
/* Stack is below GDT */
|
||||
gd->start_addr_sp = dest_addr;
|
||||
|
||||
/* U-Boot is below the stack */
|
||||
@ -107,31 +97,6 @@ int calculate_relocation_address(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_gd_to_ram_f_r(void)
|
||||
{
|
||||
gd_t *ram_gd;
|
||||
|
||||
/*
|
||||
* Global data is still in temporary memory (the CPU cache).
|
||||
* calculate_relocation_address() has set gd->new_gd_addr to
|
||||
* where the global data lives in RAM but getting it there
|
||||
* safely is a bit tricky due to the 'F-Segment Hack' that
|
||||
* we need to use for x86
|
||||
*/
|
||||
ram_gd = (gd_t *)gd->new_gd_addr;
|
||||
memcpy((void *)ram_gd, gd, sizeof(gd_t));
|
||||
|
||||
/*
|
||||
* Reload the Global Descriptor Table so FS points to the
|
||||
* in-RAM copy of Global Data (calculate_relocation_address()
|
||||
* has already calculated the in-RAM location of the GDT)
|
||||
*/
|
||||
ram_gd->gd_addr = (ulong)ram_gd;
|
||||
init_gd(ram_gd, (u64 *)gd->gdt_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_cache_f_r(void)
|
||||
{
|
||||
/* Initialise the CPU cache(s) */
|
||||
|
@ -32,8 +32,6 @@ include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(BOARD).o
|
||||
|
||||
COBJS-y += coreboot.o
|
||||
COBJS-$(CONFIG_PCI) += coreboot_pci.o
|
||||
SOBJS-y += coreboot_start16.o
|
||||
SOBJS-y += coreboot_start.o
|
||||
|
||||
|
37
board/chromebook-x86/coreboot/config.mk
Normal file
37
board/chromebook-x86/coreboot/config.mk
Normal file
@ -0,0 +1,37 @@
|
||||
#
|
||||
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Alternatively, this software may be distributed under the terms of the
|
||||
# GNU General Public License ("GPL") version 2 as published by the Free
|
||||
# Software Foundation.
|
||||
#
|
||||
|
||||
HOSTCFLAGS_autoconf.mk.dep = -Wno-variadic-macros
|
@ -22,19 +22,6 @@
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* 16bit initialization code.
|
||||
* This code have to map the area of the boot flash
|
||||
* that is used by U-boot to its final destination.
|
||||
*/
|
||||
|
||||
.text
|
||||
.section .start16, "ax"
|
||||
.code16
|
||||
.globl board_init16
|
||||
board_init16:
|
||||
jmp board_init16_ret
|
||||
|
||||
.section .bios, "ax"
|
||||
.code16
|
||||
.globl realmode_reset
|
||||
|
@ -37,7 +37,7 @@
|
||||
#define CONFIG_SYS_COREBOOT
|
||||
#undef CONFIG_SHOW_BOOT_PROGRESS
|
||||
#define CONFIG_LAST_STAGE_INIT
|
||||
|
||||
#define CONFIG_X86_NO_RESET_VECTOR
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Watchdog Configuration
|
||||
@ -67,6 +67,10 @@
|
||||
CONFIG_SYS_SCSI_MAX_LUN)
|
||||
#endif
|
||||
|
||||
/* Generic TPM interfaced through LPC bus */
|
||||
#define CONFIG_GENERIC_LPC_TPM
|
||||
#define CONFIG_TPM_TIS_BASE_ADDRESS 0xfed40000
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Real Time Clock Configuration
|
||||
*/
|
||||
@ -210,12 +214,11 @@
|
||||
* (128kB + Environment Sector Size) malloc pool
|
||||
*/
|
||||
#define CONFIG_SYS_STACK_SIZE (32 * 1024)
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (256 * 1024 + 16 * 1024)
|
||||
#define CONFIG_SYS_CAR_ADDR 0x19200000
|
||||
#define CONFIG_SYS_CAR_SIZE (16 * 1024)
|
||||
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
|
||||
#define CONFIG_SYS_MONITOR_LEN (256 * 1024)
|
||||
#define CONFIG_SYS_MALLOC_LEN (0x20000 + 128 * 1024)
|
||||
/* Address of temporary Global Data */
|
||||
#define CONFIG_SYS_INIT_GD_ADDR (256 * 1024)
|
||||
|
||||
|
||||
/* allow to overwrite serial and ethaddr */
|
||||
|
@ -168,16 +168,10 @@
|
||||
#define CONFIG_SYS_STACK_SIZE (32 * 1024)
|
||||
#define CONFIG_SYS_CAR_ADDR 0x19200000
|
||||
#define CONFIG_SYS_CAR_SIZE (16 * 1024)
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_CAR_ADDR + \
|
||||
CONFIG_SYS_CAR_SIZE)
|
||||
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
|
||||
#define CONFIG_SYS_MONITOR_LEN (256 * 1024)
|
||||
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SECT_SIZE + \
|
||||
128*1024)
|
||||
/* Address of temporary Global Data */
|
||||
#define CONFIG_SYS_INIT_GD_ADDR CONFIG_SYS_CAR_ADDR
|
||||
|
||||
|
||||
/* allow to overwrite serial and ethaddr */
|
||||
#define CONFIG_ENV_OVERWRITE
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user