android lk解读 (2)

本文详细解析了嵌入式平台的初始化过程,包括时钟配置、中断控制器初始化、定时器初始化及安全调用管理等关键步骤。通过具体函数解释了如何针对不同硬件进行初始化设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看看

void platform_clock_init(void)
{
	if (platform_is_msm8939() || platform_is_msm8929())
		msm8939_clock_override();
	clk_init(msm_clocks_8916, ARRAY_SIZE(msm_clocks_8916));
}
先判断平台

然后

void msm8939_clock_override()
{
	mdss_mdp_clk_src.freq_tbl = ftbl_mdss_mdp_clk_src;
}
这个有讲究

static struct clk_freq_tbl ftbl_mdss_mdp_clk_src[] = {
	F_MM( 50000000,   gpll0,  16,    0,    0),
	F_MM( 80000000,   gpll0,  10,    0,    0),
	F_MM( 100000000,  gpll0,   8,    0,    0),
	F_MM( 153600000,  gpll1,   4,    0,    0),
	F_MM( 160000000,  gpll0,   5,    0,    0),
	F_MM( 177780000,  gpll0, 4.5,    0,    0),
	F_MM( 200000000,  gpll0,   4,    0,    0),
	F_MM( 266670000,  gpll0,   3,    0,    0),
	F_MM( 307200000,  gpll1,   2,    0,    0),
	F_END
};
看看

#define F_MM(f, s, div, m, n) \
	{ \
		.freq_hz = (f), \
		.src_clk = &s##_clk_src.c, \
		.m_val = (m), \
		.n_val = ~((n)-(m)) * !!(n), \
		.d_val = ~(n),\
		.div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
			| BVAL(10, 8, s##_mm_source_val), \
	}
然后看

void clk_init(struct clk_lookup *clist, unsigned num)
{
	if(clist && num)
	{
		msm_clk_list.clist = (struct clk_lookup *)clist;
		msm_clk_list.num = num;
	}
}
这个

static struct clk_lookup msm_clocks_8916[] =
{
	CLK_LOOKUP("sdc1_iface_clk", gcc_sdcc1_ahb_clk.c),
	CLK_LOOKUP("sdc1_core_clk",  gcc_sdcc1_apps_clk.c),
};
看看

#define CLK_LOOKUP(con, c) { .con_id = con, .clk = &c }

再看

#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))

也就是多用宏定义来完成一些值

接着是第三个函数

void qgic_init(void)
{
	qgic_dist_init();
	qgic_cpu_init();
}
一个一个看

/* Intialize distributor */
static void qgic_dist_init(void)
{
	uint32_t i;
	uint32_t num_irq = 0;
	uint32_t cpumask;

	cpumask = qgic_get_cpumask();

	cpumask |= cpumask << 8;
	cpumask |= cpumask << 16;

	/* Disabling GIC */
	writel(0, GIC_DIST_CTRL);     //#define writel(v, a) (*REG32(a) = (v))

	/*
	 * Find out how many interrupts are supported.
	 */
	num_irq = readl(GIC_DIST_CTR) & 0x1f;   //#define readl(a) (*REG32(a))
	num_irq = (num_irq + 1) * 32;

	/* Set each interrupt line to use N-N software model
	 * and edge sensitive, active high
	 */
	for (i = 32; i < num_irq; i += 16)
		writel(0xffffffff, GIC_DIST_CONFIG + i * 4 / 16);

	writel(0xffffffff, GIC_DIST_CONFIG + 4);

	/* Set up interrupts for this CPU */
	for (i = 32; i < num_irq; i += 4)
		writel(cpumask, GIC_DIST_TARGET + i * 4 / 4);

	/* Set priority of all interrupts */

	/*
	 * In bootloader we dont care about priority so
	 * setting up equal priorities for all
	 */
	for (i = 0; i < num_irq; i += 4)
		writel(0xa0a0a0a0, GIC_DIST_PRI + i * 4 / 4);

	/* Disabling interrupts */
	for (i = 0; i < num_irq; i += 32)
		writel(0xffffffff, GIC_DIST_ENABLE_CLEAR + i * 4 / 32);

	writel(0x0000ffff, GIC_DIST_ENABLE_SET);

	/*Enabling GIC */
	writel(1, GIC_DIST_CTRL);
}
还有一个

static void qgic_cpu_init(void)
{
	writel(0xf0, GIC_CPU_PRIMASK);
	writel(1, GIC_CPU_CTRL);
}
看看第四个

void qtimer_init()
{
	ticks_per_sec = qtimer_get_frequency();
}
接着

/* Function to return the frequency of the timer */
uint32_t qtimer_get_frequency()
{
	uint32_t freq;

	/* Read the Global counter frequency */
	__asm__ volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq));

	return freq;

}

看看第五个

void scm_init()
{
	int ret;

	ret = scm_arm_support_available(SCM_SVC_INFO, IS_CALL_AVAIL_CMD);

	if (ret)
		dprintf(CRITICAL, "Failed to initialize SCM\n");
}

接着

static int scm_arm_support_available(uint32_t svc_id, uint32_t cmd_id)
{
	int ret;

	ret = is_scm_call_available(SCM_SVC_INFO, IS_CALL_AVAIL_CMD);

	if (ret > 0)
		scm_arm_support = true;

	return ret;
}
最后

int is_scm_call_available(uint32_t svc_id, uint32_t cmd_id)
{
	uint32_t ret;
	scmcall_arg scm_arg = {0};
	scmcall_ret scm_ret = {0};

	scm_arg.x0 = MAKE_SIP_SCM_CMD(SCM_SVC_INFO, IS_CALL_AVAIL_CMD);
	scm_arg.x1 = MAKE_SCM_ARGS(0x1);
	scm_arg.x2 = MAKE_SIP_SCM_CMD(svc_id, cmd_id);

	ret = scm_call2(&scm_arg, &scm_ret);

	if (!ret)
		return scm_ret.x1;

	return ret;
}
typedef struct {
<span style="white-space:pre">	</span>uint32_t x0;/* command ID details as per ARMv8 spec :
<span style="white-space:pre">					</span>0:7 command, 8:15 service id
<span style="white-space:pre">					</span>0x02000000: SIP calls
<span style="white-space:pre">					</span>30: SMC32 or SMC64
<span style="white-space:pre">					</span>31: Standard or fast calls*/
<span style="white-space:pre">	</span>uint32_t x1; /* # of args and attributes for buffers
<span style="white-space:pre">				</span>  * 0-3: arg #
<span style="white-space:pre">				</span>  * 4-5: type of arg1
<span style="white-space:pre">				</span>  * 6-7: type of arg2
<span style="white-space:pre">				</span>  * :
<span style="white-space:pre">				</span>  * :
<span style="white-space:pre">				</span>  * 20-21: type of arg8
<span style="white-space:pre">				</span>  * 22-23: type of arg9
<span style="white-space:pre">				</span>  */
<span style="white-space:pre">	</span>uint32_t x2; /* Param1 */
<span style="white-space:pre">	</span>uint32_t x3; /* Param2 */
<span style="white-space:pre">	</span>uint32_t x4; /* Param3 */
<span style="white-space:pre">	</span>uint32_t x5[10]; /* Indirect parameter list */
<span style="white-space:pre">	</span>uint32_t atomic; /* To indicate if its standard or fast call */
} scmcall_arg;
完成一些初始化,需要porting guide来看


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值