mirror of
https://github.com/physwizz/a155-U-u1.git
synced 2024-11-19 13:27:49 +00:00
179 lines
4.0 KiB
C
179 lines
4.0 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) 2015 MediaTek Inc.
|
|
*/
|
|
|
|
#define E_EX(member) e_rrr_##member
|
|
#define E_PER_CPU_EX(member) e_rrr_per_cpu_##member
|
|
#define DF(member, fmt) E_EX(member)
|
|
#define DF_A(member, fmt, total) E_EX(member)
|
|
#define DF_S(member, fmt) E_EX(member)
|
|
#define DF_PER_CPU(member, fmt) E_PER_CPU_EX(member)
|
|
enum {
|
|
#include "desc_def.h"
|
|
E_EX(num_total),
|
|
};
|
|
|
|
enum {
|
|
#include "desc_def_per_cpu.h"
|
|
E_PER_CPU_EX(num_total),
|
|
};
|
|
|
|
enum DESC_DATA_TYPE_SPECIAL {
|
|
D_SEG_SINGLE_BYTE = 0xabe,
|
|
D_SINGLE_VALUE = 0xaee,
|
|
D_PER_CPU_VALUE = 0xaed,
|
|
};
|
|
|
|
#define FMT_MAX_LEN 128
|
|
struct rrr_desc_data {
|
|
/* D_SINGLE_VARIABLE : single;
|
|
* D_PER_CPU_VALUE : per cpu;
|
|
* D_SEG_SINGLE_BYTE : segmented into single byte;
|
|
* > 0 : array
|
|
* == 0 : invalid
|
|
*/
|
|
uint32_t type;
|
|
/* offset in structure of last_reboot_reason */
|
|
uint32_t off;
|
|
/* varaible type e.g. char size=1; uint32_t size=4; uint64_t size=8; */
|
|
uint32_t size;
|
|
/* real size of fmt string for seq_printf */
|
|
uint32_t fmtsize;
|
|
char fmt[FMT_MAX_LEN];
|
|
};
|
|
|
|
struct rrr_desc {
|
|
uint32_t magic;
|
|
uint32_t version;
|
|
uint32_t off_pl;
|
|
uint32_t off_linux;
|
|
uint32_t off_desc_data;
|
|
uint32_t total;
|
|
uint32_t per_cpu_total;
|
|
uint32_t cpu_num;
|
|
uint32_t fmt_max_len;
|
|
uint32_t reserve[6];
|
|
uint32_t magic_end;
|
|
struct rrr_desc_data desc[E_EX(num_total)];
|
|
struct rrr_desc_data per_cpu_desc[E_PER_CPU_EX(num_total)];
|
|
};
|
|
|
|
#undef DF
|
|
#define DF(member, fmt) \
|
|
[E_EX(member)] = fmt
|
|
#undef DF_A
|
|
#define DF_A(member, fmt, total) \
|
|
[E_EX(member)] = fmt
|
|
#undef DF_S
|
|
#define DF_S(member, fmt) \
|
|
[E_EX(member)] = fmt
|
|
#undef DF_PER_CPU
|
|
#define DF_PER_CPU(member, fmt) \
|
|
[E_PER_CPU_EX(member)] = fmt
|
|
static char *buf[] = {
|
|
#include "desc_def.h"
|
|
};
|
|
|
|
static char *per_cpu_buf[] = {
|
|
#include "desc_def_per_cpu.h"
|
|
};
|
|
|
|
static struct last_reboot_reason dummy_var;
|
|
#define DF_C(type, member) { \
|
|
type, \
|
|
offsetof(struct last_reboot_reason, member), \
|
|
sizeof(typeof(dummy_var.member)) \
|
|
}
|
|
|
|
#undef DF
|
|
#define DF(member, fmt) \
|
|
[E_EX(member)] = DF_C(D_SINGLE_VALUE, member)
|
|
#undef DF_A
|
|
#define DF_A(member, fmt, total) \
|
|
[E_EX(member)] = DF_C(total, member[0])
|
|
#undef DF_S
|
|
#define DF_S(member, fmt) \
|
|
[E_EX(member)] = DF_C(D_SEG_SINGLE_BYTE, member)
|
|
#undef DF_PER_CPU
|
|
#define DF_PER_CPU(member, fmt) \
|
|
[E_PER_CPU_EX(member)] = DF_C(D_PER_CPU_VALUE, member[0])
|
|
static struct rrr_desc /*__maybe_unused*/ idesc_init = {
|
|
REBOOT_REASON_SIG,
|
|
0x100,
|
|
sizeof(struct mboot_params_buffer),
|
|
0x0,
|
|
(offsetof(struct rrr_desc, desc)),
|
|
E_EX(num_total),
|
|
E_PER_CPU_EX(num_total),
|
|
AEE_MTK_CPU_NUMS,
|
|
FMT_MAX_LEN,
|
|
{0},
|
|
REBOOT_REASON_SIG,
|
|
{
|
|
#include "desc_def.h"
|
|
},
|
|
/* per cpu */
|
|
{
|
|
#include "desc_def_per_cpu.h"
|
|
}
|
|
};
|
|
|
|
static struct rrr_desc *idesc;
|
|
|
|
#define IDESC_ADDR ((unsigned long)idesc)
|
|
#define IDESC_SIZE (sizeof(struct rrr_desc))
|
|
static uint32_t start_pos;
|
|
#define IDESC_START_POS ((unsigned long)&start_pos)
|
|
|
|
static int mboot_params_init_desc(uint32_t off_linux)
|
|
{
|
|
int i;
|
|
size_t len;
|
|
|
|
idesc = kzalloc(IDESC_SIZE, GFP_KERNEL);
|
|
if (!idesc)
|
|
return -1;
|
|
|
|
memcpy(idesc, &idesc_init, IDESC_SIZE);
|
|
idesc->off_linux = off_linux;
|
|
idesc->cpu_num = nr_cpu_ids;
|
|
for (i = 0; i < E_EX(num_total); i++) {
|
|
if (buf[i]) {
|
|
len = strlen(buf[i]);
|
|
if (len < FMT_MAX_LEN) {
|
|
strncpy(idesc->desc[i].fmt,
|
|
buf[i], FMT_MAX_LEN);
|
|
idesc->desc[i].fmt[FMT_MAX_LEN - 1] = '\0';
|
|
idesc->desc[i].fmtsize = len;
|
|
} else {
|
|
/* idesc->desc[i].size = i; */
|
|
idesc->desc[i].type = 0x0;
|
|
}
|
|
} else {
|
|
/* idesc->desc[i].size = i; */
|
|
idesc->desc[i].type = 0x0;
|
|
}
|
|
}
|
|
for (i = 0; i < E_PER_CPU_EX(num_total); i++) {
|
|
if (per_cpu_buf[i]) {
|
|
len = strlen(per_cpu_buf[i]);
|
|
if (len < FMT_MAX_LEN) {
|
|
strncpy(idesc->per_cpu_desc[i].fmt,
|
|
per_cpu_buf[i], FMT_MAX_LEN);
|
|
idesc->per_cpu_desc[i].fmt[FMT_MAX_LEN - 1] =
|
|
'\0';
|
|
idesc->per_cpu_desc[i].fmtsize =
|
|
strlen(idesc->per_cpu_desc[i].fmt);
|
|
} else {
|
|
/* idesc->per_cpu_desc[i].size = i; */
|
|
idesc->per_cpu_desc[i].type = 0x0;
|
|
}
|
|
} else {
|
|
/* idesc->per_cpu_desc[i].size = i; */
|
|
idesc->per_cpu_desc[i].type = 0x0;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|