Unverified Commit 3765928a authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!4596 add sw64 architecture support

Merge Pull Request from: @guzitao 
 
Add support for sunway architecture platforms: sw3231, sw831 and sw6432.

These patches generally cover the following tasks:
1. add support for stacktrace, qspinlock, perf events, kexec, kdump, eBPF-jit, suspend, hibernation, kernel-relocation, ftrace, kprobe/uprobe, jump_label, kgdb, dynamic-frequency-scaling, dynamic-turning-on-off-cores
2. fix build support

Test:
All features pass the test.

Related issues:
https://gitee.com/openeuler/kernel/issues/I8Y8CY
https://gitee.com/openeuler/kernel/issues/I8YRFO
https://gitee.com/openeuler/kernel/issues/I8YR3H
https://gitee.com/openeuler/kernel/issues/I5PNGJ
https://gitee.com/openeuler/kernel/issues/I8YR76
https://gitee.com/openeuler/kernel/issues/I8YQW8
https://gitee.com/openeuler/kernel/issues/I8YRCP
https://gitee.com/openeuler/kernel/issues/I8YQUV 
 
Link:https://gitee.com/openeuler/kernel/pulls/4596

 

Reviewed-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents a9c5e94c 8e69e090
Loading
Loading
Loading
Loading
+66 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */

#ifndef _ASM_SW64_CPUFREQ_H
#define _ASM_SW64_CPUFREQ_H

#include <linux/kref.h>
#include <linux/list.h>
#include <linux/seq_file.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>

struct clk;

extern char curruent_policy[CPUFREQ_NAME_LEN];

struct clk_ops {
	void (*init)(struct clk *clk);
	void (*enable)(struct clk *clk);
	void (*disable)(struct clk *clk);
	void (*recalc)(struct clk *clk);
	int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id);
	long (*round_rate)(struct clk *clk, unsigned long rate);
};

struct clk {
	struct list_head node;
	const char *name;
	int id;
	struct module *owner;

	struct clk *parent;
	const struct clk_ops *ops;

	struct kref kref;

	unsigned long rate;
	unsigned long flags;
};

#define CLK_ALWAYS_ENABLED	(1 << 0)
#define CLK_RATE_PROPAGATES	(1 << 1)

#define CLK_PRT         0x1UL
#define CORE_CLK0_V     (0x1UL << 1)
#define CORE_CLK0_R     (0x1UL << 2)
#define CORE_CLK2_V     (0x1UL << 15)
#define CORE_CLK2_R     (0x1UL << 16)

#define CLK_LV1_SEL_PRT         0x1UL
#define CLK_LV1_SEL_MUXA        (0x1UL << 2)
#define CLK_LV1_SEL_MUXB        (0x1UL << 3)

#define CORE_PLL0_CFG_SHIFT     4
#define CORE_PLL2_CFG_SHIFT     18

extern struct cpufreq_frequency_table freq_table[];

int clk_init(void);
void sw64_set_rate(unsigned int index);

struct clk *sw64_clk_get(struct device *dev, const char *id);

void sw64_update_clockevents(unsigned long cpu, u32 freq);

unsigned int __sw64_cpufreq_get(struct cpufreq_policy *policy);
#endif /* _ASM_SW64_CPUFREQ_H */
+9 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_SW64_CPUTIME_H
#define _ASM_SW64_CPUTIME_H

typedef u64 __nocast cputime64_t;

#define jiffies64_to_cputime64(__jif)  ((__force cputime64_t)(__jif))

#endif /* _ASM_SW64_CPUTIME_H */
+44 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * arch/sw_64/include/asm/ftrace.h
 *
 * Copyright (C) 2019, serveros, linyue
 *
 * 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.
 */
#ifndef _ASM_SW64_FTRACE_H
#define _ASM_SW64_FTRACE_H

#define MCOUNT_ADDR		((unsigned long)_mcount)
#define MCOUNT_INSN_SIZE	20	/* 5 * SW64_INSN_SIZE */
#define MCOUNT_LDGP_SIZE	8	/* 2 * SW64_INSN_SIZE */

#define ARCH_SUPPORTS_FTRACE_OPS 1

#ifndef __ASSEMBLY__
#include <linux/compat.h>
#include <asm/insn.h>


extern void _mcount(unsigned long);

struct dyn_arch_ftrace {
	/* No extra data needed for sw64 */
};

extern unsigned long ftrace_graph_call;


static inline unsigned long ftrace_call_adjust(unsigned long addr)
{
	/*
	 * addr is the address of the mcount call instruction.
	 * recordmcount does the necessary offset calculation.
	 */
	return addr;
}

#endif /* ifndef __ASSEMBLY__ */
#endif /* _ASM_SW64_FTRACE_H */
+50 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */

#ifndef _ASM_SW64_JUMP_LABEL_H
#define _ASM_SW64_JUMP_LABEL_H

#ifndef __ASSEMBLY__

#include <linux/types.h>
#include <asm/insn.h>

#define JUMP_LABEL_NOP_SIZE		SW64_INSN_SIZE

static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
{
	asm_volatile_goto("1: nop\n\t"
			".pushsection __jump_table,  \"aw\"\n\t"
			".align 3\n\t"
			".quad 1b, %l[l_yes], %0\n\t"
			".popsection\n\t"
			:  :  "i"(&((char *)key)[branch]) :  : l_yes);

	return false;
l_yes:
	return true;
}

static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
{
	asm_volatile_goto("1: br %l[l_yes]\n\t"
			".pushsection __jump_table,  \"aw\"\n\t"
			".align 3\n\t"
			".quad 1b, %l[l_yes], %0\n\t"
			".popsection\n\t"
			:  :  "i"(&((char *)key)[branch]) :  : l_yes);

	return false;
l_yes:
	return true;
}

typedef u64 jump_label_t;

struct jump_entry {
	jump_label_t code;
	jump_label_t target;
	jump_label_t key;
};

#endif /* __ASSEMBLY__ */
#endif /* _ASM_SW64_JUMP_LABEL_H */
+82 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_SW64_KEXEC_H
#define _ASM_SW64_KEXEC_H

#ifdef CONFIG_KEXEC

/* Maximum physical address we can use pages from */
#define KEXEC_SOURCE_MEMORY_LIMIT	(-1UL)
/* Maximum address we can reach in physical address mode */
#define KEXEC_DESTINATION_MEMORY_LIMIT	(-1UL)
/* Maximum address we can use for the control code buffer */
#define KEXEC_CONTROL_MEMORY_LIMIT	(-1UL)

#define KEXEC_CONTROL_PAGE_SIZE		8192

#define KEXEC_ARCH			KEXEC_ARCH_SW64

#define KEXEC_SW64_ATAGS_OFFSET		0x1000
#define KEXEC_SW64_ZIMAGE_OFFSET	0x8000

#ifndef __ASSEMBLY__

/**
 * crash_setup_regs() - save registers for the panic kernel
 * @newregs: registers are saved here
 * @oldregs: registers to be saved (may be %NULL)
 *
 * Function copies machine registers from @oldregs to @newregs. If @oldregs is
 * %NULL then current registers are stored there.
 */
static inline void crash_setup_regs(struct pt_regs *newregs,
				    struct pt_regs *oldregs)
{
	if (oldregs) {
		memcpy(newregs, oldregs, sizeof(*newregs));
	} else {
		__asm__ __volatile__ ("stl $0, %0" : "=m" (newregs->regs[0]));
		__asm__ __volatile__ ("stl $1, %0" : "=m" (newregs->regs[1]));
		__asm__ __volatile__ ("stl $2, %0" : "=m" (newregs->regs[2]));
		__asm__ __volatile__ ("stl $3, %0" : "=m" (newregs->regs[3]));
		__asm__ __volatile__ ("stl $4, %0" : "=m" (newregs->regs[4]));
		__asm__ __volatile__ ("stl $5, %0" : "=m" (newregs->regs[5]));
		__asm__ __volatile__ ("stl $6, %0" : "=m" (newregs->regs[6]));
		__asm__ __volatile__ ("stl $7, %0" : "=m" (newregs->regs[7]));
		__asm__ __volatile__ ("stl $8, %0" : "=m" (newregs->regs[8]));
		__asm__ __volatile__ ("stl $9, %0" : "=m" (newregs->regs[9]));
		__asm__ __volatile__ ("stl $10, %0" : "=m" (newregs->regs[10]));
		__asm__ __volatile__ ("stl $11, %0" : "=m" (newregs->regs[11]));
		__asm__ __volatile__ ("stl $12, %0" : "=m" (newregs->regs[12]));
		__asm__ __volatile__ ("stl $13, %0" : "=m" (newregs->regs[13]));
		__asm__ __volatile__ ("stl $14, %0" : "=m" (newregs->regs[14]));
		__asm__ __volatile__ ("stl $15, %0" : "=m" (newregs->regs[15]));
		__asm__ __volatile__ ("stl $16, %0" : "=m" (newregs->regs[16]));
		__asm__ __volatile__ ("stl $17, %0" : "=m" (newregs->regs[17]));
		__asm__ __volatile__ ("stl $18, %0" : "=m" (newregs->regs[18]));
		__asm__ __volatile__ ("stl $19, %0" : "=m" (newregs->regs[19]));
		__asm__ __volatile__ ("stl $20, %0" : "=m" (newregs->regs[20]));
		__asm__ __volatile__ ("stl $21, %0" : "=m" (newregs->regs[21]));
		__asm__ __volatile__ ("stl $22, %0" : "=m" (newregs->regs[22]));
		__asm__ __volatile__ ("stl $23, %0" : "=m" (newregs->regs[23]));
		__asm__ __volatile__ ("stl $24, %0" : "=m" (newregs->regs[24]));
		__asm__ __volatile__ ("stl $25, %0" : "=m" (newregs->regs[25]));
		__asm__ __volatile__ ("stl $26, %0" : "=m" (newregs->regs[26]));
		__asm__ __volatile__ ("stl $27, %0" : "=m" (newregs->regs[27]));
		__asm__ __volatile__ ("stl $28, %0" : "=m" (newregs->regs[28]));
		__asm__ __volatile__ ("stl $29, %0" : "=m" (newregs->regs[29]));
		__asm__ __volatile__ ("stl $30, %0" : "=m" (newregs->regs[30]));
		newregs->pc = (unsigned long)current_text_addr();
	}
}

/* Function pointer to optional machine-specific reinitialization */
extern void (*kexec_reinit)(void);

#endif /* __ASSEMBLY__ */

struct kimage;
extern unsigned long kexec_args[4];

#endif /* CONFIG_KEXEC */

#endif /* _ASM_SW64_KEXEC_H */
Loading