PD#118612: cortex-a53: fix ARM CPU errata 843419, 845719, 835769

1. Support toolchain both Linaro gcc 4.9.2 and 5.2
2. Fix ARM errata for issue 843419, 845719, 835769.
3. Fix comiple error due to toolchain update.
4. Change psci call of smc & hvc from inline assemble to assemble
   files, in order to avoid register arguments order problem due
   to toolchain

Conflicts:
	drivers/amlogic/amlnf/dev/phydev.c
	drivers/amlogic/display/lcd/lcd_common.c
	drivers/amlogic/hdmi/hdmi_tx_20/hw/hdcpVerify.c
	drivers/amlogic/jtag/jtag_setup.c
	drivers/amlogic/mmc/amlsd.c

Change-Id: I70f849b7496b434277c22eb961189c51b2417cb6
This commit is contained in:
Tao Zeng
2016-01-25 15:40:58 +08:00
committed by codewalker
parent d9eb56a2cd
commit 8940e2dfda
22 changed files with 184 additions and 88 deletions

View File

@@ -167,6 +167,55 @@ config ARM_AMBA
endmenu
menu "ARM errata workarounds via the alternatives framework"
config ARM64_ERRATUM_845719
bool "Cortex-A53: 845719: a load might read incorrect data"
depends on COMPAT
default y
help
This option adds an alternative code sequence to work around ARM
erratum 845719 on Cortex-A53 parts up to r0p4.
When running a compat (AArch32) userspace on an affected Cortex-A53
part, a load at EL0 from a virtual address that matches the bottom 32
bits of the virtual address used by a recent load at (AArch64) EL1
might return incorrect data.
The workaround is to write the contextidr_el1 register on exception
return to a 32-bit task.
Please note that this does not necessarily enable the workaround,
as it depends on the alternative framework, which will only patch
the kernel if an affected CPU is detected.
If unsure, say Y.
config ARM64_ERRATUM_843419
bool "Cortex-A53: 843419: A load or store might access an incorrect address"
depends on MODULES
default y
help
This option builds kernel modules using the large memory model in
order to avoid the use of the ADRP instruction, which can cause
a subsequent memory access to use an incorrect address on Cortex-A53
parts up to r0p4.
Note that the kernel itself must be linked with a version of ld
which fixes potentially affected ADRP instructions through the
use of veneers.
If unsure, say Y.
config ARM64_ERRATUM_835769
bool "Cortex-A53: 835769: AArch64 multiply-accumulate instruction might produce incorrect result"
depends on MODULES
default y
help
This option build kernel with option -mfix-cortex-a53-835769 to
fix mulity-accumulate bug of cpu
endmenu
menu "Kernel Features"
config ARM64_64K_PAGES

View File

@@ -35,6 +35,15 @@ comma = ,
CHECKFLAGS += -D__aarch64__
ifeq ($(CONFIG_ARM64_ERRATUM_843419), y)
KBUILD_CFLAGS_MODULE += $(call cc-option,-mfix-cortex-a53-843419)
endif
ifeq ($(CONFIG_ARM64_ERRATUM_835769), y)
KBUILD_CFLAGS_MODULE += $(call cc-option,-mfix-cortex-a53-835769)
endif
$(info KBUILD_CFLAGS_MODULE:$(KBUILD_CFLAGS_MODULE))
# Default value
head-y := arch/arm64/kernel/head.o

View File

@@ -246,6 +246,13 @@ CONFIG_ARCH_MESON64_ODROIDC2=y
#
CONFIG_ARM_AMBA=y
#
# ARM errata workarounds via the alternatives framework
#
CONFIG_ARM64_ERRATUM_845719=y
CONFIG_ARM64_ERRATUM_843419=y
CONFIG_ARM64_ERRATUM_835769=y
#
# Kernel Features
#

View File

@@ -246,6 +246,13 @@ CONFIG_ARCH_MESON64_ODROIDC2=y
#
CONFIG_ARM_AMBA=y
#
# ARM errata workarounds via the alternatives framework
#
CONFIG_ARM64_ERRATUM_845719=y
CONFIG_ARM64_ERRATUM_843419=y
CONFIG_ARM64_ERRATUM_835769=y
#
# Kernel Features
#

View File

@@ -16,4 +16,7 @@
int psci_init(void);
int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1, u64 arg2);
int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2);
#endif /* __ASM_PSCI_H */

View File

@@ -14,7 +14,7 @@ arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \
entry-fpsimd.o process.o ptrace.o setup.o signal.o \
sys.o stacktrace.o time.o traps.o io.o vdso.o \
hyp-stub.o psci.o cpu_ops.o insn.o return_address.o \
opcodes.o
opcodes.o psci-call.o
arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
sys_compat.o

View File

@@ -116,6 +116,16 @@
.if \el == 0
ct_user_enter
ldr x23, [sp, #S_SP] // load return stack pointer
#ifdef CONFIG_ARM64_ERRATUM_845719
tbz x22, #4, 1f
#ifdef CONFIG_PID_IN_CONTEXTIDR
mrs x29, contextidr_el1
msr contextidr_el1, x29
#else
msr contextidr_el1, xzr
#endif
1:
#endif
.endif
.if \ret
ldr x1, [sp, #S_X1] // preserve x0 (syscall return)

View File

@@ -0,0 +1,28 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Copyright (C) 2015 ARM Limited
*
* Author: Will Deacon <will.deacon@arm.com>
*/
#include <linux/linkage.h>
/* int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */
ENTRY(__invoke_psci_fn_hvc)
hvc #0
ret
ENDPROC(__invoke_psci_fn_hvc)
/* int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */
ENTRY(__invoke_psci_fn_smc)
smc #0
ret
ENDPROC(__invoke_psci_fn_smc)

View File

@@ -95,40 +95,6 @@ static u32 psci_power_state_pack(struct psci_power_state state)
<< PSCI_POWER_STATE_AFFL_SHIFT);
}
/*
* The following two functions are invoked via the invoke_psci_fn pointer
* and will not be inlined, allowing us to piggyback on the AAPCS.
*/
static noinline int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1,
u64 arg2)
{
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
__asmeq("%3", "x3")
"hvc #0\n"
: "+r" (function_id)
: "r" (arg0), "r" (arg1), "r" (arg2));
return function_id;
}
static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
u64 arg2)
{
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
__asmeq("%3", "x3")
"smc #0\n"
: "+r" (function_id)
: "r" (arg0), "r" (arg1), "r" (arg2));
return function_id;
}
static int psci_cpu_suspend(struct psci_power_state state,
unsigned long entry_point)
{

View File

@@ -1134,6 +1134,56 @@ static void show_phydev_info(void)
}
}
/*
this function alloc phydev and init it.
*/
int aml_alloc_phydev(struct amlnand_phydev **phydev_pp,
struct amlnand_chip *aml_chip,
struct dev_para **dev_para,
int dev_idx)
{
int ret = 0;
struct hw_controller *controller = &(aml_chip->controller);
/*struct nand_config *config = aml_chip->config_ptr;*/
struct nand_flash *flash = &(aml_chip->flash);
struct amlnand_phydev *phydev_p = NULL;
*phydev_pp = aml_nand_malloc(sizeof(struct amlnand_phydev));
if (*phydev_pp == NULL) {
aml_nand_msg("malloc failed need %lx here",
(sizeof(struct amlnand_phydev)));
ret = -NAND_MALLOC_FAILURE;
return ret;
}
phydev_p = *phydev_pp;
memset(phydev_p, 0, sizeof(struct amlnand_phydev));
phydev_p->priv = aml_chip;
*dev_para = &aml_chip->config_ptr->dev_para[dev_idx];
memcpy((void *)&phydev_p->name,
&(*dev_para)->name, MAX_DEVICE_NAME_LEN*sizeof(char));
/*set default parameter*/
phydev_p->writesize = flash->pagesize;
phydev_p->erasesize = flash->blocksize;
phydev_p->oobavail = controller->oobavail;
phydev_p->writesize_shift = ffs(phydev_p->writesize) - 1;
phydev_p->erasesize_shift = ffs(phydev_p->erasesize) - 1;
phydev_p->write = nand_write;
phydev_p->read = nand_read;
phydev_p->erase = nand_erase;
phydev_p->block_isbad = nand_block_isbad;
phydev_p->block_markbad = nand_block_markbad;
phydev_p->block_modifybbt = block_modifybbt;
phydev_p->update_bbt = update_bbt;
phydev_p->phydev_test_block = nand_test_block;
#ifndef AML_NAND_UBOOT
phydev_p->suspend = phydev_suspend;
phydev_p->resume = phydev_resume;
#endif
return ret;
}
/******
*nand chip usage

View File

@@ -519,7 +519,7 @@ static DEFINE_MUTEX(video_module_mutex);
static DEFINE_SPINLOCK(lock);
static u32 frame_par_ready_to_set, frame_par_force_to_set;
static u32 vpts_remainder;
static bool video_property_changed;
static int video_property_changed;
static u32 video_notify_flag;
static int enable_video_discontinue_report = 1;

View File

@@ -44,6 +44,7 @@
#include <linux/amlogic/hdmi_tx/hdmi_tx_ddc.h>
/*#include <linux/amlogic/hdmi_tx/hdmi_tx_cec.h>*/
#include <linux/reset.h>
#include <linux/compiler.h>
#include "mach_reg.h"
#include "hdmi_tx_reg.h"
@@ -254,7 +255,6 @@ int hdmitx_ddc_hw_op(enum ddc_op cmd)
return ret;
}
#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
int hdmitx_hdcp_opr(unsigned int val)
{
if (val == 1) {

View File

@@ -124,7 +124,7 @@ inline int32_t get_reading(void)
stk_readb(STK_ALS_DT2_REG));
}
inline int32_t alscode2lux(int32_t alscode)
int32_t alscode2lux(int32_t alscode)
{
/*R-set Def --> 500KOhm ==> x 5
IT --> x1

View File

@@ -30,6 +30,8 @@
#include <asm/compiler.h>
#ifndef CONFIG_ARM64
#include <asm/opcodes-sec.h>
#else
#include <asm/psci.h>
#endif
#if 0
void meson_regmap_lock(void *p)
@@ -296,16 +298,7 @@ static noinline int __invoke_sec_fn_smc(u32 function_id, u32 arg0, u32 arg1,
static noinline int __invoke_sec_fn_smc(u32 function_id, u32 arg0, u32 arg1,
u32 arg2)
{
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
__asmeq("%3", "x3")
"smc #0\n"
: "+r" (function_id)
: "r" (arg0), "r" (arg1), "r" (arg2));
return function_id;
return __invoke_psci_fn_smc(function_id, arg0, arg1, arg2);
}
#endif

View File

@@ -613,7 +613,7 @@ void aml_sdhc_clear_fifo(struct amlsd_host *host)
}
/*enable irq bit in reg SDHC_ICTL*/
inline void aml_sdhc_enable_imask(struct amlsd_host *host, u32 irq)
void aml_sdhc_enable_imask(struct amlsd_host *host, u32 irq)
{
u32 ictl = readl(host->base+SDHC_ICTL);
ictl |= irq;
@@ -621,7 +621,7 @@ inline void aml_sdhc_enable_imask(struct amlsd_host *host, u32 irq)
}
/*disable irq bit in reg SDHC_ICTL*/
inline void aml_sdhc_disable_imask(struct amlsd_host *host, u32 irq)
void aml_sdhc_disable_imask(struct amlsd_host *host, u32 irq)
{
u32 ictl = readl(host->base+SDHC_ICTL);
ictl &= ~irq;

View File

@@ -224,25 +224,6 @@ ssize_t time_out_store(struct device *dev, struct device_attribute *attr,
DEVICE_ATTR(time_out, 0666, time_out_show, time_out_store);
static int suspend_reason;
static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
u64 arg2)
{
register long x0 asm("x0") = function_id;
register long x1 asm("x1") = arg0;
register long x2 asm("x2") = arg1;
register long x3 asm("x3") = arg2;
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
__asmeq("%3", "x3")
"smc #0\n"
: "+r" (x0)
: "r" (x1), "r" (x2), "r" (x3));
return x0;
}
ssize_t suspend_reason_show(struct device *dev, struct device_attribute *attr,
char *buf)
{

View File

@@ -96,14 +96,13 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
if (req->cmd_flags & REQ_DISCARD)
return tr->discard(dev, block, nsect);
switch(rq_data_dir(req)) {
case READ:
if (rq_data_dir(req) == READ) {
for (; nsect > 0; nsect--, block++, buf += tr->blksize)
if (tr->readsect(dev, block, buf))
return -EIO;
rq_flush_dcache_pages(req);
return 0;
case WRITE:
} else {
if (!tr->writesect)
return -EIO;
@@ -112,9 +111,6 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
if (tr->writesect(dev, block, buf))
return -EIO;
return 0;
default:
printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
return -EIO;
}
}

View File

@@ -683,7 +683,7 @@ static inline void early_init_dt_check_for_initrd(unsigned long node)
#include <linux/version.h>
int is_instabooting;
inline void early_init_dt_check_for_instaboot(unsigned long node)
void early_init_dt_check_for_instaboot(unsigned long node)
{
unsigned long version_code;
int len;

View File

@@ -2695,9 +2695,9 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
char __user *, type, unsigned long, flags, void __user *, data)
{
int ret;
char *kernel_type;
char *kernel_type = NULL;
struct filename *kernel_dir;
char *kernel_dev;
char *kernel_dev = NULL;
unsigned long data_page;
ret = copy_mount_string(type, &kernel_type);

View File

@@ -2964,16 +2964,13 @@ int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle,
struct nfs_fsinfo *info,
bool auth_probe)
{
int status;
int status = 0;
switch (auth_probe) {
case false:
if (!auth_probe)
status = nfs4_lookup_root(server, fhandle, info);
if (status != -NFS4ERR_WRONGSEC)
break;
default:
if (auth_probe || status == NFS4ERR_WRONGSEC)
status = nfs4_do_find_root_sec(server, fhandle, info);
}
if (status == 0)
status = nfs4_server_capabilities(server, fhandle);

View File

@@ -51,7 +51,7 @@ static const unsigned char lzop_magic[] = {
#define HEADER_SIZE_MIN (9 + 7 + 4 + 8 + 1 + 4)
#define HEADER_SIZE_MAX (9 + 7 + 1 + 8 + 8 + 4 + 1 + 255 + 4)
STATIC inline int INIT parse_header(u8 *input, int *skip, int in_len)
STATIC int INIT parse_header(u8 *input, int *skip, int in_len)
{
int l;
u8 *parse = input;
@@ -108,7 +108,7 @@ STATIC inline int INIT parse_header(u8 *input, int *skip, int in_len)
return 1;
}
STATIC inline int INIT unlzo(u8 *input, int in_len,
STATIC int INIT unlzo(u8 *input, int in_len,
int (*fill) (void *, unsigned int),
int (*flush) (void *, unsigned int),
u8 *output, int *posp,

View File

@@ -527,7 +527,7 @@ __vma_address(struct page *page, struct vm_area_struct *vma)
return vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
}
inline unsigned long
static inline unsigned long
vma_address(struct page *page, struct vm_area_struct *vma)
{
unsigned long address = __vma_address(page, vma);