강좌 & 팁
안녕하세요~ 호서대학교 석사(과정) 이우영 입니다.
오늘은 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를 보면 무슨 작업을 하는지 알 수 있습니다.
먼저 75라인에서 DSB를 해서 data를 보호하고,
76라인에서 인터럽트를 기다리면 sleep를 시작합니다.
이렇게 인터럽트가 발생 할때 까지 idle 상태에 들어가게 됩니다.
여기까지 idle에 대한 것이였습니다.
그럼 이 함수가 어떻게 연결 되었는지 확인을 해보도록 하겠습니다.
리눅스의 grep 명열어로 소스코드에서 s3c6410_idle을 찾아 보았습니다.
s3c64xx_idle 에 s3c6410_dile 함수 주소를 입력해줍니다.
그럼 s3c64xx_idle 함수를 찾아볼까요?
s3c64xx_idle는 arch/arm/mach-s3c6400/include/mach/system.h 에서 호출 됩니다.
찾아가 보니 arch_idle 함수에서 호출 하고 있습니다.
aech_idle 함수는 전에 default_idle 함수에서 호출을 해줬습니다.
이로써 s3c6410은 default_idle 을 통해 pw를 관리 한다는것을 알 수 있었습니다.
역으로 함수를 찾아가는것도 나쁘지 않죠? ㅎㅎ
오늘도 여기까지 그럼 다음시간에 만나요~
http://ms-osek.org/ <- 쫌더 빨리 보고 싶으신분은 여기로 오세요~