Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* Copyright (C) 2017 Andes Technology Corporation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #ifndef _ASM_RISCV_MODULE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #define _ASM_RISCV_MODULE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <asm-generic/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) struct module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) unsigned long module_emit_got_entry(struct module *mod, unsigned long val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) unsigned long module_emit_plt_entry(struct module *mod, unsigned long val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #ifdef CONFIG_MODULE_SECTIONS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) struct mod_section {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 	Elf_Shdr *shdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	int num_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	int max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) struct mod_arch_specific {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	struct mod_section got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	struct mod_section plt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	struct mod_section got_plt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) struct got_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	unsigned long symbol_addr;	/* the real variable address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static inline struct got_entry emit_got_entry(unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	return (struct got_entry) {val};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static inline struct got_entry *get_got_entry(unsigned long val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 					      const struct mod_section *sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	struct got_entry *got = (struct got_entry *)(sec->shdr->sh_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	for (i = 0; i < sec->num_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		if (got[i].symbol_addr == val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 			return &got[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) struct plt_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	 * Trampoline code to real target address. The return address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	 * should be the original (pc+4) before entring plt entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	u32 insn_auipc;		/* auipc t0, 0x0                       */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	u32 insn_ld;		/* ld    t1, 0x10(t0)                  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	u32 insn_jr;		/* jr    t1                            */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define OPC_AUIPC  0x0017
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define OPC_LD     0x3003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define OPC_JALR   0x0067
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define REG_T0     0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define REG_T1     0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) static inline struct plt_entry emit_plt_entry(unsigned long val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 					      unsigned long plt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 					      unsigned long got_plt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	 * U-Type encoding:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	 * +------------+----------+----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	 * | imm[31:12] | rd[11:7] | opc[6:0] |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	 * +------------+----------+----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	 * I-Type encoding:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	 * +------------+------------+--------+----------+----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	 * | imm[31:20] | rs1[19:15] | funct3 | rd[11:7] | opc[6:0] |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	 * +------------+------------+--------+----------+----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	unsigned long offset = got_plt - plt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	u32 hi20 = (offset + 0x800) & 0xfffff000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	u32 lo12 = (offset - hi20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	return (struct plt_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		OPC_AUIPC | (REG_T0 << 7) | hi20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		OPC_LD | (lo12 << 20) | (REG_T0 << 15) | (REG_T1 << 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		OPC_JALR | (REG_T1 << 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static inline int get_got_plt_idx(unsigned long val, const struct mod_section *sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	struct got_entry *got_plt = (struct got_entry *)sec->shdr->sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	for (i = 0; i < sec->num_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		if (got_plt[i].symbol_addr == val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static inline struct plt_entry *get_plt_entry(unsigned long val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 					      const struct mod_section *sec_plt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 					      const struct mod_section *sec_got_plt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	struct plt_entry *plt = (struct plt_entry *)sec_plt->shdr->sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	int got_plt_idx = get_got_plt_idx(val, sec_got_plt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (got_plt_idx >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		return plt + got_plt_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #endif /* CONFIG_MODULE_SECTIONS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #endif /* _ASM_RISCV_MODULE_H */