head.s分析(18):init_pda

系统 2125 0

快乐虾

http://blog.csdn.net/lights_joy/

lights@hb165.com

本文适用于

ADI bf561 DSP

uclinux-2008r1.5-rc3 ( 移植到 vdsp5)

Visual DSP++ 5.0(update 5)

欢迎转载,但请保留作者信息

sp += -12;

call _init_pda;

sp += 12;

init_pda 的定义在 linux-2.6.x\arch\blackfin\mm\init.c 文件中。这是 SMP 相关的代码所调用的第一个函数。

PDA ,即 Per-processor Data Areas ,一看就知道是每个核的私有财产,呵呵。

asmlinkage void init_pda( void )

{

unsigned int cpu = raw_smp_processor_id();

/* Initialize the PDA fields holding references to other parts

of the memory. The content of such memory is still

undefined at the time of the call, we are only setting up

valid pointers to it. */

memset(cpu_pda, 0, sizeof (*cpu_pda));

#ifdef CONFIG_MPU

#else

write_pda(ipdt, ipdt_tables[cpu]);

#ifdef CONFIG_CPLB_INFO

write_pda(ipdt_swapcount, ipdt_swapcount_tables[cpu]);

write_pda(dpdt_swapcount, dpdt_swapcount_tables[cpu]);

#endif

write_pda(dpdt, dpdt_tables[cpu]);

#endif

write_pda(ex_stack, exception_stacks[cpu + 1]);

#ifdef CONFIG_SMP

write_pda(imask, 0x1f);

#endif

}

1.1.1 获取 DSPID

首先,它调用了 raw_smp_processor_id 来获取当前核的序号,对于 561 ,如果运行这段代码的是 A 核,将返回 0 B 核则返回 1

#define raw_smp_processor_id() blackfin_core_id()

#define blackfin_core_id() (bfin_read_DSPID() & 0xff)

#define bfin_read_DSPID() bfin_read32(DSPID)

DSPID

1.1.2 cpu_pda

cpu_pda 定义为:

#define cpu_pda (( struct blackfin_pda *)get_l1_scratch_start())

#define get_l1_scratch_start() get_l1_scratch_start_cpu(blackfin_core_id())

#define get_l1_scratch_start_cpu(cpu) \

({ unsigned long __addr; \

__addr = (cpu) ? L1_SCRATCH_COREB : L1_SCRATCH_COREA; \

__addr; })

即它将使用每个核各自的 l1 scratchpad(4k) 来存放私有数据。 cpu_pda 即指向这段存储空间的最低位置,并将之转换为 ( struct blackfin_pda *) 。看看这个结构体的定义:

/* Per-processor Data Areas are located at the start of the L1 scratch

memory, so that each can be accessed at a fixed address from the

current CPU. Used for SMP support and process stack checking. */

struct pda_task_info {

/* Points to the start of the stack. */

void *stack_start;

/* Not updated by the kernel; a user process can modify this to

keep track of the lowest address of the stack pointer during its

runtime. */

void *lowest_sp;

};

struct blackfin_pda { /* Per-processor Data Area */

struct pda_task_info task_info;

#ifdef CONFIG_SMP

unsigned long imask; /* Current IMASK value */

#endif

unsigned long *ipdt; /* Start of switchable I-CPLB table */

unsigned long *ipdt_swapcount; /* Number of swaps in ipdt */

unsigned long *dpdt; /* Start of switchable D-CPLB table */

unsigned long *dpdt_swapcount; /* Number of swaps in dpdt */

/*

* Single instructions can have multiple faults, which

* need to be handled by traps.c, in irq5. We store

* the exception cause to ensure we don't miss a

* double fault condition

*/

unsigned long ex_iptr;

unsigned long ex_optr;

unsigned long ex_buf[4];

unsigned long ex_imask; /* Saved imask from exception */

unsigned long *ex_stack; /* Exception stack space */

#ifdef ANOMALY_05000261

unsigned long last_cplb_fault_retx;

#endif

};

4K 的大小还远着呢,还有扩展的潜力,呵呵。

1.1.3 write_pda

这个宏定义为:

#define write_pda(field, val) \

do { \

cpu_pda->field = val; \

} while (0)

就是对 cpu_pda 的各个字段赋值。

这里涉及的几个数组,其定义如下:

u_long ipdt_tables[NR_CPUS][MAX_SWITCH_I_CPLBS+1];

u_long dpdt_tables[NR_CPUS][MAX_SWITCH_D_CPLBS+1];

#ifdef CONFIG_CPLB_INFO

u_long ipdt_swapcount_tables[NR_CPUS][MAX_SWITCH_I_CPLBS];

u_long dpdt_swapcount_tables[NR_CPUS][MAX_SWITCH_D_CPLBS];

#endif

extern unsigned long exception_stacks[NR_CPUS][1024];

head.s分析(18):init_pda


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论