안녕하세요~ 호서대학교 석사(과정) 이우영 입니다.

오늘은 cpu_idle을 마무리 질려고 하지만 쉽지가 않습니다 (ㅎㅎㅎ.)

아무리 찾아도 pm_idle 값이 NULL이 나옵니다 ㅎㅎ

그래서 역으로 추적 하기로 했습니다

우리가 테스트 하고 있는 프로세서는 s3c6410 입니다.

arm11(armv6)을 사용하고 있습니다.

arch/arm/mach-s3c6410/cpu.c 를 보면

static void s3c6410_idle(void)
{
unsigned long tmp;

/* Ensure our idle mode is to go to idle */
/* Set WFI instruction to SLEEP mode */

tmp = __raw_readl(S3C_PWR_CFG);
tmp &= ~(0x3<<5);
tmp |= (0x1<<5);
__raw_writel(tmp, S3C_PWR_CFG);

cpu_do_idle();
}

위와 같이 s3c6410_idle 함수가 있습니다.

S3C_PWR_CFG 레지스터의 값을 읽어 6-5번 비트를 01로 세팅하여 SLEEP 모드로 변경 해줍니다.

( s3c6410 datasheet의 3.3.5.5 SLEEP mode 를 참고하세요 친절하게 영어로 써있습니다 ㅎㅎ)

그리고 cpu_do_idle 함수를 호출 합니다.

(이건 메크로라서 armv6_do_idle로 변환 됩니다.)

armv6_do_idle 는 arch/arm/mm/proc-v6.S 에 다음과 같이 나와있습니다.

66/*
67 * cpu_v6_do_idle()
68 *
69 * Idle the processor (eg, wait for interrupt).
70 *
71 * IRQs are already disabled.
72 */
73ENTRY(cpu_v6_do_idle)
74 mov r1, #0
75 mcr p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode
76 mcr p15, 0, r1, c7, c0, 4 @ wait for interrupt
77 mov pc, lr

ARM1176JZ-S™ datasheet를 보면 무슨 작업을 하는지 알 수 있습니다.

코프로세서.PNG

먼저 75라인에서 DSB를 해서 data를 보호하고,

76라인에서 인터럽트를 기다리면 sleep를 시작합니다.

이렇게 인터럽트가 발생 할때 까지 idle 상태에 들어가게 됩니다.

여기까지 idle에 대한 것이였습니다.

그럼 이 함수가 어떻게 연결 되었는지 확인을 해보도록 하겠습니다.

리눅스의 grep 명열어로 소스코드에서 s3c6410_idle을 찾아 보았습니다.

 s3c6410_idle.PNG

s3c64xx_idle 에 s3c6410_dile 함수 주소를 입력해줍니다.

그럼 s3c64xx_idle 함수를 찾아볼까요?

 s3c64xx_idle.PNG

s3c64xx_idle는 arch/arm/mach-s3c6400/include/mach/system.h 에서 호출 됩니다.

 s3c64xx_idle호출.PNG

찾아가 보니 arch_idle 함수에서 호출 하고 있습니다.

aech_idle 함수는 전에 default_idle 함수에서 호출을 해줬습니다.

이로써 s3c6410은 default_idle 을 통해 pw를 관리 한다는것을 알 수 있었습니다.

역으로 함수를 찾아가는것도 나쁘지 않죠? ㅎㅎ

오늘도 여기까지 그럼 다음시간에 만나요~

 

http://ms-osek.org/ <- 쫌더 빨리 보고 싶으신분은 여기로 오세요~