顯示具有 s3c2410 標籤的文章。 顯示所有文章
顯示具有 s3c2410 標籤的文章。 顯示所有文章

2007年7月31日 星期二

SLC ECC Correction in S3C2440

S3C24xx都內建有NAND Flash Controller,而且都支援NAND Flash Boot。NAND Flash 和NOR Flash 相比,除了不能用linear addressing的方式來access外,就是NAND Flash有「允許bit error」的特性,所以在實際的使用上,就要配合ECC 來correct。

NAND Flash Controller中NFECCSAT0就NFESTAT0 (0x4E000024) ,用來表示以下:

  • Main Area
  • Spare Area
兩個區域的「哪個byte中的哪個bit是錯的」,這就是NAND flash Controller提供的hardware ECC 功能。

S3C2440只支援SLC,因為只有內建1 bite ECC,也就是說只能correct 1 bit的錯誤。S3C2443則內建4 bit的ECC,最多可以correct到4 bit的錯誤,所以可以support MLC。

SLC和MLC除了1 time programming的限制外,就是容易產生的Error bit 數。
  • SLC保證 99.9999% 的chip 只會產生最多 1 bit的error。
  • MLC要到99.9999%的程度,會有 4 bit error。
(以上的% 是僅供參考)

回到NFESTAT0,要correct bit error,首先要check一下 error的狀態,以bit[1.0],[3.2] 分別代表兩個區域的error狀態:
  • 00 : No Error - Lucky
  • 01 : 1 bit error - Correct 回來
  • 10 : Multiple error - 沒救了
  • 11 : ECC area error - 沒救 (?)
所以,需要作ECC correct的,只有在 01 的時候。

然後讀出 Error bit 所在的byte位置和bit位置,分別是
  • Byte 位置 bit[17:7], bit[24:21]
  • Bit 位置 bit[6:4], bit[20:18]
所以correction 的動作
 *(ReadBuf + ByteNo) ^= ( 1 << BitNo ) 

SECCD 就是 Spare-area ECC Data
MECCD 就是 Main-area ECC Data

2007年7月30日 星期一

Baudrate set in S3C2443

S3C2442 的UART Baurdate可設定的更細微,提供兩個register :

  1. UBDIV : 整數部份
  2. UDIVSLOT : 小數部份
設定的計算為:
整數 + 小數 = SRCCLK/ (baudratex16) - 1
以115200, SRCCLK=40MHz為例
整數 + 小數 = 40000000/(115200 x 16) - 1 = 20.7
所以
整數 = 20
小數 = 0.7
因此,UBRDIV = 20

小數部份與UDIVSLOT的關係是
小數 = UDIVSLOT 中 bit是1的數量 / 16
所以
0.7 = 1's number in UDIVSLOT / 16
1's number in UDIVSOLT = 11
UDIVSLOT有很多種組合,只要讓1的個數是11即可,Samsung建議,個數為11時,UDIVSOLT用 0xDDDD。

2007年7月28日 星期六

筆記:Into Idle

在設定完chip register,進入idle mode後,還要program co-processor:
這一篇 http://nocash.emubase.de/gbatek.htm 有說明到ARM CP15 Cache Control。

Cn,Cm,Op2 Rd   Command
C7,C0,4 0 Wait For Interrupt (Halt)
另外在linux kernel code中也有:
/*
* cpu_arm926_do_idle()
*/
.align 5
ENTRY(cpu_arm926_do_idle)
#if defined(CONFIG_CPU_ARM926_CPU_IDLE)
mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
#endif
mov pc, lr
ref SystemIdle Function:
MMU_WaitInterrupt(void)
mov  r0,#0x0
mcr p15,0,r0,c7,c0,4
mov pc,lr
所以,這是要cache 進入idle mode,等待interrupt 的意思 ?

S3C2412有三種Power mode:
  1. IDLE
  2. STOP
  3. SLEEP
是利用PWRMODECON 這個register來設定。

說是這樣說,但是Samsung的BSP code卻沒有這樣作,完全沒用PWRMODECON,反而是用 PWRCFG。其中的STANDBYWFI 佔2 bit,設定後,可以進入:
  • IDLE : 01b
  • STOP : 10b
  • SLEEP : 11b
這種利用寫入 PWRMODECON 的STANDBYWFIbit 的作法,在datasheet 中稱作是 "mcr p15, 0, r0, c7, c0, 4"。

datasheet 中「很好心」地為大家提供一個 "alternat method to set STANDBYWFI" :就是用剛剛的cp15 command:

mcr  p15,0,r0,c7,c0,4
但是沒有說明相當於command的哪一個信號? 01b, 10b, 11b ?

對照datasheet和BSP code:

STANDBYWFI 進入IDLE是 01b。
BSP code用 mcr cp15 command 進入時,Rd (在此用r0),卻是設定成 #0x0。

而且這是datasheet中有關"進入STOP Mode"的說明中寫的,BSP code卻是在進入idle mode 的code中使用的。

接著有一個table,說明進入三個mode的方法:
  • IDLE - STANDBYWFI
  • STOP - CMD or STANDBYWFI
  • SLEEP - CMD or STANDBYWFI
STANDBYWFI 的意思大概可瞭解,雖然有點不清楚,那麼"CMD"是什麼 ?是寫入command到PWRMODECON的MODESLEEP 嗎?

2007年7月27日 星期五

External Interrupt in S3C2440

S3C2440的EINT (Extend INT)中斷示意
s3c2440int

EINT也算是SUB INTERRUPT,但是完全沒有相似於SUBSRCPND的解說。只有register 說明,而且是安排在GPIO的部份... (好吧,該GPIO的mux function有Interrupt,所以算OK吧)

偉大的EINT的registerg的說明中,EINTMASK、EINTPEND這兩個register只有table,沒有多餘的說明。

本來以為EINTPEND是指「經過mask後的interrupt」,結果不是,是mask前。所以要處理 EINT時要這注意,要將 EINTPEND和EINTMASK「處理」後,才是真正產生中斷的中斷源。


跟trigger mode有關係,當是外部controller觸發,設定成edge trigger時,因為未回應外部controller時,trigger signal不會改變,不會再有一次edge波形發生,所以即使先ACK這個INT也沒關係。反而是未能要能正確,無漏失的catch next edge,ISR要儘快的ACK這個interrupt,免得edge 出現時,interrupt還未ACK而miss。

.. 真是麻煩呀...

這樣的連動是不是要用class包裝起來?當設定edge trigger,該isr先ACK。當設定level triiger,作post ACK?

回到上面的圖,SRCPND經過priority arbitration,Mask後,選出一個bit 到INTPND。實際產生中斷。

INTPND和SRCPND都是要「手動」清除的。
DataSheet (14. Interrupt Controller - Interrupt Pending Register) 是說..
Like the SRCPND register, this reister has to be cleaned in interrupt service routine after cleaning the SRCPND register.
所以,中斷發生後,一定要clear SRCPND和INTPND。而且順序是
  1. SRCPND
  2. INTPND
原因和上面說的一樣..如果先clear到INTPND,但是SRCPND還沒清,則同一個中斷馬上又從SRCPND浮上來,導致一樣的INTPND。

2007年5月6日 星期日

反組譯 OpenMoko Steppingstone Code

在正式的內文之前,先來說個小故事。前一陣子在Atmel AT91RM9200這顆ARM9微處理器的實驗板上寫了一個簡單又迷你的kernel,後來想想認識的人裡面都沒人玩這顆,不免有點孤單。於是打算把它移植到比較多人玩並且有模擬器可用的平台,剛好jserv推薦OpenMoko,OpenMoko 的第一支手機Neo1973/GTA01所使用的微處理器是Samsung S3C2410也是 ARM9,我想應該不難移植,還有jserv掛保證的模擬器可用,所以就決定來玩OpenMoko/S3C2410啦!

既然我的出發點是要開發kernel,那麼對於處理器的啟動程序就不可不知。S3C2410啟動時,會從NAND flash的開頭複製4KB 內容到內部的SRAM,然後跳到SRAM開始執行,這4KB SRAM就稱為Steppingstone。這段小程式就是處理器最先執行的程式,但4KB空間當然放不下U-Boot,於是我們只把這段小程式當作踏腳石(steppingstone),由它來幫忙載入完整的U-Boot bootloader。

在好奇心作祟之下,想來看看這段steppingstone code寫些什麼(其實也沒什麼,真的很無聊吧 XD)。在 http://buildhost.openmoko.org/tmp/deploy/images/ 抓了lowlevel_foo開頭檔名的".bin" 檔,問題是我只知道可以用arm-linux-objdump來反組譯 ELF 格式的程式,那麼binary檔怎麼反組譯呢?上網Google了一下沒有找到ARM反組譯器(其實是前幾個連結沒有就懶得繼續找了),網友說IDA Pro這套軟體可以反組譯ARM程式,但我懶得安裝這麼龐大的東西。只好換個關鍵字繼續 Google 看看,結果找到了這個網頁:

firmware_reverse_engeneering_methodology
原來可以把binary檔轉成ELF檔再進行反組譯,方法如下:

先把binary轉成ELF格式:
$ arm-linux-objcopy -I binary -O elf32-littlearm foo.bin foo.elf
再進行反組譯:
$ arm-linux-objdump -marm9 -D foo.elf > foo.asm
輸出結果foo.asm是個純文字檔,內容就是反組譯出來的組合語言。簡單吧?不需要安裝其它軟體,只要利用toolchain就能辦到。學會這招後,手邊如果有實驗板沒開放bootloader原始碼,或者想hack PDA bootloader,都不是問題啦(當然得有耐心去trace組合語言程式碼)!