RISC-V: Fix the rv32i kernel build
These patches for building 32-bit RISC-V kernel. - Fix the compile errors and warnings on RV32I. - Fix some incompatible problem on RV32I. - Add format.h for compatible of print format. The fixed width integer types format for Elf_Addr will move to generic header by another patch. For now, there are some warning about unexpected argument of type on RV32I. Change in v1: - Fix some error in v1 - Remove implementation of fixed width integer types format for Elf_Addr.
This commit is contained in:
Коммит
9a6a51154f
|
@ -107,6 +107,7 @@ config ARCH_RV32I
|
||||||
select GENERIC_LIB_ASHLDI3
|
select GENERIC_LIB_ASHLDI3
|
||||||
select GENERIC_LIB_ASHRDI3
|
select GENERIC_LIB_ASHRDI3
|
||||||
select GENERIC_LIB_LSHRDI3
|
select GENERIC_LIB_LSHRDI3
|
||||||
|
select GENERIC_LIB_UCMPDI2
|
||||||
|
|
||||||
config ARCH_RV64I
|
config ARCH_RV64I
|
||||||
bool "RV64I"
|
bool "RV64I"
|
||||||
|
|
|
@ -21,8 +21,13 @@ typedef struct user_regs_struct elf_gregset_t;
|
||||||
|
|
||||||
typedef union __riscv_fp_state elf_fpregset_t;
|
typedef union __riscv_fp_state elf_fpregset_t;
|
||||||
|
|
||||||
#define ELF_RISCV_R_SYM(r_info) ((r_info) >> 32)
|
#if __riscv_xlen == 64
|
||||||
#define ELF_RISCV_R_TYPE(r_info) ((r_info) & 0xffffffff)
|
#define ELF_RISCV_R_SYM(r_info) ELF64_R_SYM(r_info)
|
||||||
|
#define ELF_RISCV_R_TYPE(r_info) ELF64_R_TYPE(r_info)
|
||||||
|
#else
|
||||||
|
#define ELF_RISCV_R_SYM(r_info) ELF32_R_SYM(r_info)
|
||||||
|
#define ELF_RISCV_R_TYPE(r_info) ELF32_R_TYPE(r_info)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RISC-V relocation types
|
* RISC-V relocation types
|
||||||
|
|
|
@ -37,7 +37,7 @@ static int apply_r_riscv_64_rela(struct module *me, u32 *location, Elf_Addr v)
|
||||||
static int apply_r_riscv_branch_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_branch_rela(struct module *me, u32 *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
s64 offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - (void *)location;
|
||||||
u32 imm12 = (offset & 0x1000) << (31 - 12);
|
u32 imm12 = (offset & 0x1000) << (31 - 12);
|
||||||
u32 imm11 = (offset & 0x800) >> (11 - 7);
|
u32 imm11 = (offset & 0x800) >> (11 - 7);
|
||||||
u32 imm10_5 = (offset & 0x7e0) << (30 - 10);
|
u32 imm10_5 = (offset & 0x7e0) << (30 - 10);
|
||||||
|
@ -50,7 +50,7 @@ static int apply_r_riscv_branch_rela(struct module *me, u32 *location,
|
||||||
static int apply_r_riscv_jal_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_jal_rela(struct module *me, u32 *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
s64 offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - (void *)location;
|
||||||
u32 imm20 = (offset & 0x100000) << (31 - 20);
|
u32 imm20 = (offset & 0x100000) << (31 - 20);
|
||||||
u32 imm19_12 = (offset & 0xff000);
|
u32 imm19_12 = (offset & 0xff000);
|
||||||
u32 imm11 = (offset & 0x800) << (20 - 11);
|
u32 imm11 = (offset & 0x800) << (20 - 11);
|
||||||
|
@ -63,7 +63,7 @@ static int apply_r_riscv_jal_rela(struct module *me, u32 *location,
|
||||||
static int apply_r_riscv_rcv_branch_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_rcv_branch_rela(struct module *me, u32 *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
s64 offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - (void *)location;
|
||||||
u16 imm8 = (offset & 0x100) << (12 - 8);
|
u16 imm8 = (offset & 0x100) << (12 - 8);
|
||||||
u16 imm7_6 = (offset & 0xc0) >> (6 - 5);
|
u16 imm7_6 = (offset & 0xc0) >> (6 - 5);
|
||||||
u16 imm5 = (offset & 0x20) >> (5 - 2);
|
u16 imm5 = (offset & 0x20) >> (5 - 2);
|
||||||
|
@ -78,7 +78,7 @@ static int apply_r_riscv_rcv_branch_rela(struct module *me, u32 *location,
|
||||||
static int apply_r_riscv_rvc_jump_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_rvc_jump_rela(struct module *me, u32 *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
s64 offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - (void *)location;
|
||||||
u16 imm11 = (offset & 0x800) << (12 - 11);
|
u16 imm11 = (offset & 0x800) << (12 - 11);
|
||||||
u16 imm10 = (offset & 0x400) >> (10 - 8);
|
u16 imm10 = (offset & 0x400) >> (10 - 8);
|
||||||
u16 imm9_8 = (offset & 0x300) << (12 - 11);
|
u16 imm9_8 = (offset & 0x300) << (12 - 11);
|
||||||
|
@ -96,7 +96,7 @@ static int apply_r_riscv_rvc_jump_rela(struct module *me, u32 *location,
|
||||||
static int apply_r_riscv_pcrel_hi20_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_pcrel_hi20_rela(struct module *me, u32 *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
s64 offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - (void *)location;
|
||||||
s32 hi20;
|
s32 hi20;
|
||||||
|
|
||||||
if (offset != (s32)offset) {
|
if (offset != (s32)offset) {
|
||||||
|
@ -178,7 +178,7 @@ static int apply_r_riscv_lo12_s_rela(struct module *me, u32 *location,
|
||||||
static int apply_r_riscv_got_hi20_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_got_hi20_rela(struct module *me, u32 *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
s64 offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - (void *)location;
|
||||||
s32 hi20;
|
s32 hi20;
|
||||||
|
|
||||||
/* Always emit the got entry */
|
/* Always emit the got entry */
|
||||||
|
@ -200,7 +200,7 @@ static int apply_r_riscv_got_hi20_rela(struct module *me, u32 *location,
|
||||||
static int apply_r_riscv_call_plt_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_call_plt_rela(struct module *me, u32 *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
s64 offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - (void *)location;
|
||||||
s32 fill_v = offset;
|
s32 fill_v = offset;
|
||||||
u32 hi20, lo12;
|
u32 hi20, lo12;
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ static int apply_r_riscv_call_plt_rela(struct module *me, u32 *location,
|
||||||
static int apply_r_riscv_call_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_call_rela(struct module *me, u32 *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
s64 offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - (void *)location;
|
||||||
s32 fill_v = offset;
|
s32 fill_v = offset;
|
||||||
u32 hi20, lo12;
|
u32 hi20, lo12;
|
||||||
|
|
||||||
|
@ -347,7 +347,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
|
||||||
for (j = 0; j < sechdrs[relsec].sh_size / sizeof(*rel); j++) {
|
for (j = 0; j < sechdrs[relsec].sh_size / sizeof(*rel); j++) {
|
||||||
u64 hi20_loc =
|
unsigned long hi20_loc =
|
||||||
sechdrs[sechdrs[relsec].sh_info].sh_addr
|
sechdrs[sechdrs[relsec].sh_info].sh_addr
|
||||||
+ rel[j].r_offset;
|
+ rel[j].r_offset;
|
||||||
u32 hi20_type = ELF_RISCV_R_TYPE(rel[j].r_info);
|
u32 hi20_type = ELF_RISCV_R_TYPE(rel[j].r_info);
|
||||||
|
@ -360,12 +360,12 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
|
||||||
Elf_Sym *hi20_sym =
|
Elf_Sym *hi20_sym =
|
||||||
(Elf_Sym *)sechdrs[symindex].sh_addr
|
(Elf_Sym *)sechdrs[symindex].sh_addr
|
||||||
+ ELF_RISCV_R_SYM(rel[j].r_info);
|
+ ELF_RISCV_R_SYM(rel[j].r_info);
|
||||||
u64 hi20_sym_val =
|
unsigned long hi20_sym_val =
|
||||||
hi20_sym->st_value
|
hi20_sym->st_value
|
||||||
+ rel[j].r_addend;
|
+ rel[j].r_addend;
|
||||||
|
|
||||||
/* Calculate lo12 */
|
/* Calculate lo12 */
|
||||||
u64 offset = hi20_sym_val - hi20_loc;
|
size_t offset = hi20_sym_val - hi20_loc;
|
||||||
if (IS_ENABLED(CONFIG_MODULE_SECTIONS)
|
if (IS_ENABLED(CONFIG_MODULE_SECTIONS)
|
||||||
&& hi20_type == R_RISCV_GOT_HI20) {
|
&& hi20_type == R_RISCV_GOT_HI20) {
|
||||||
offset = module_emit_got_entry(
|
offset = module_emit_got_entry(
|
||||||
|
|
|
@ -28,7 +28,9 @@ static void __init zone_sizes_init(void)
|
||||||
{
|
{
|
||||||
unsigned long max_zone_pfns[MAX_NR_ZONES] = { 0, };
|
unsigned long max_zone_pfns[MAX_NR_ZONES] = { 0, };
|
||||||
|
|
||||||
|
#ifdef CONFIG_ZONE_DMA32
|
||||||
max_zone_pfns[ZONE_DMA32] = PFN_DOWN(min(4UL * SZ_1G, max_low_pfn));
|
max_zone_pfns[ZONE_DMA32] = PFN_DOWN(min(4UL * SZ_1G, max_low_pfn));
|
||||||
|
#endif
|
||||||
max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
|
max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
|
||||||
|
|
||||||
free_area_init_nodes(max_zone_pfns);
|
free_area_init_nodes(max_zone_pfns);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче