青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 60, 文章 - 0, 評論 - 197, 引用 - 0
數(shù)據(jù)加載中……

s3c2410 MMU 啟用后設(shè)置中斷跳轉(zhuǎn)指令遇到的問題

事情是這樣的, 前些日子在 FS2410 (核心板為三星 s3c2410)開發(fā)板上實現(xiàn)了中斷,包括
響應(yīng)時鐘 Timer0, 響應(yīng)按鍵,并實現(xiàn)了串口通信,能把任何數(shù)據(jù)通過 UART0 發(fā)送到 PC 機(jī)
上的超級終端上進(jìn)行顯示,這樣也便于調(diào)試。前兩天又實現(xiàn)了 MMU 的啟用代碼,歡呼雀躍
啊..., 可就在這個時候問題來了...

MMU 啟用后中斷不能響應(yīng)了!, start.S 的代碼片段如下(arm-linux-gcc 匯編格式):

   text
   .global _start
   _start:
    b reset
    NOP
    NOP
    NOP
    NOP
    NOP
    ldr pc ,=handle_irq
    NOP
   reset:
    ldr r0, =0x53000000  @ Close Watch-dog Timer
    mov r1, #0x0
    str r1, [r0]
  
    @ init stack
    ldr sp,=4096
    
    @ disable all interrupts
    mov r1, #0x4A000000
    mov r2, #0xffffffff
    str r2, [r1, #0x08]
    ldr r2, =0x7ff
    str r2, [r1, #0x1c]
  
    bl  memory_setup  @ Initialize memory setting
    bl  flash_to_sdram  @ Copy code to sdram
   
    ldr pc, =run_on_sdram
 run_on_sdram:
    ldr sp, =0x33000000
    bl init_mmu_tlb   @ setup page table
    bl init_mmu   @ MMU enabled
  
    msr cpsr_c, #0xd2  @ set the irq mode stack
    ldr sp, =0x31000000
    msr cpsr_c, #0xdf  @ set the system mode stack
    ldr sp, =0x32000000
    bl  init_irq           
    msr cpsr_c, #0x5f  @ set the system mode open the irq
    
    ldr sp, =0x33000000  @ Set stack pointer
    bl  main
   loop:
    b loop
  
我是通過在地址 0x00000018 放入一條長跳轉(zhuǎn)指 ldr pc, =handle_irq 來響應(yīng)中斷的,在
沒有啟用 MMU 之前,代碼工作的很好。通過如下兩個函數(shù)啟用了 MMU 實現(xiàn)虛擬內(nèi)存管理:

     bl init_mmu_tlb   @ setup page table
     bl init_mmu   @ MMU enabled

通過下面代碼來映射低端和高端中斷向量表:

  *(tb_base + 0x00000000) = (0x00000000)|(0x03<<10)|(0<<5)|(1<<4)|(1<<3)|0x02;
  *(tb_base + (0xffff0000>>20)) = VECTORS_PHY_BASE|(0x03<<10)|(0<<5)|(1<<4)|(0<<3)|0x02;

其中 VECTORS_PHY_BASE=0x33f00000, 可以看到:
通過設(shè)置頁表,將 0xffff0000 為首地址的 32 個字節(jié)的中斷向量表被映射到 0x33ff0000 為首地址的 32 字節(jié)區(qū)域,

既然設(shè)置了高端中斷向量,我們就要在 0x33ff0000 處設(shè)置中斷跳轉(zhuǎn)指令,通過調(diào)用下面這個函數(shù):

   bl  flash_to_sdram

把程序自身復(fù)制到 SDRAM 的 0x30004000為首地址的區(qū)域,而 0x30004000 前面的 16K 即 0x30000000~0x30003FFF
用來放置頁表,并且把 nand flash 的前 512byte 復(fù)制到 SDRAM 0x33ff0000 處, 因為nand flash 的前32byte 是8 個
中斷跳轉(zhuǎn)指令,這樣中斷向量表就在 0x33ff0000 處被設(shè)置。

如何讓 ARM 使用高端的中斷跳轉(zhuǎn)指令呢?通過設(shè)置 CP15 協(xié)處理器的一些寄存器來啟用。以下是內(nèi)聯(lián)匯編片段

   /*
    * turn on what we want
    * base location of exception = 0xffff0000
    */
   "orr r0, r0, #0x2000\n"
   "orr r0, r0, #0x0002\n"

   /* MMU enabled*/
   "orr r0, r0, #0x0001\n"

   /* write control register*/
   "mcr p15, 0, r0, c1, c0, 0\n"

萬事俱備,我們可以實驗了,可不幸的中斷不能響應(yīng)了?!...

......經(jīng)過了一天的折騰,發(fā)現(xiàn)將中斷跳轉(zhuǎn)指令由
   b reset
    NOP
    NOP
    NOP
    NOP
    NOP
    ldr pc,=handle_irq
    NOP

改為

   b reset
    NOP
    NOP
    NOP
    NOP
    NOP
    ldr pc, handle_irq_addr
    NOP
   handle_irq_addr: 
    .long handle_irq


中斷就能響應(yīng)了,代碼運行的很好,可百思不得其解,為什么不能用 ldr pc, =handle_irq
設(shè)置而非要用下面這種形式呢

        ldr pc, handle_irq_addr
        NOP
   handle_irq_addr: 
        .long handle_irq

我在 main 函數(shù)里通過如下代碼將所有的中斷跳轉(zhuǎn)指令(高端的和低端的)都打印出來了:

#include "serl.h"
#include "printf.h"

#define GPFCON (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)

int main()
{
  init_uart();
  GPFDAT = 0x0;
  uart_printf("starting:\n");
  unsigned long *ptr = (unsigned long *)0x30004000;
  unsigned long *ptr2 =(unsigned long *)0x33ff0000;

  unsigned long *ptr3 = (unsigned long *)0x00000000;
  unsigned long *ptr4 = (unsigned long *)0xffff0000;

  int i= 8;
  while (i--) {
    uart_printf("%x  %x  %x  %x\n", *ptr++, *ptr2++, *ptr3++, *ptr4++);
  }
  while (1);
  return 0;
}

代碼將數(shù)據(jù)通過串口在超級終端上進(jìn)行顯示后,發(fā)現(xiàn)確有微妙不同:

中斷不能響應(yīng)時(ldr pc, =handle_irq):
0x30004000 0x33ff0000 0x00000000 0xffff0000
-------------------------------------------
ea000006   ea000006   ea000006   ea000006
e1a00000   e1a00000   e1a00000   e1a00000
e1a00000   e1a00000   e1a00000   e1a00000
e1a00000   e1a00000   e1a00000   e1a00000
e1a00000   e1a00000   e1a00000   e1a00000
e1a00000   e1a00000   e1a00000   e1a00000
e59ff1fc      e59ff1fc      e59ff1fc      e59ff1fc
e1a00000   e1a00000   e1a00000   e1a00000


中斷可以響應(yīng)時(ldr pc, handle_irq_addr):
0x30004000 0x33ff0000 0x00000000 0xffff0000
-------------------------------------------
ea000007   ea000007   ea000007   ea000007
e1a00000   e1a00000   e1a00000   e1a00000
e1a00000   e1a00000   e1a00000   e1a00000
e1a00000   e1a00000   e1a00000   e1a00000
e1a00000   e1a00000   e1a00000   e1a00000
e1a00000   e1a00000   e1a00000   e1a00000
e59ff000     e59ff000     e59ff000     e59ff000
e1a00000   e1a00000   e1a00000   e1a00000


難道編譯器對這兩種跳轉(zhuǎn)產(chǎn)生了不同的影響? 將代碼反匯編來看個究竟:

中斷不能響應(yīng)時(ldr pc, =handle_irq):
---------------------------------------------------------------------
       0: ea000006  b 0x20
       4: e1a00000  nop   (mov r0,r0)
       8: e1a00000  nop   (mov r0,r0)
       c: e1a00000  nop   (mov r0,r0)
      10: e1a00000  nop   (mov r0,r0)
      14: e1a00000  nop   (mov r0,r0)
      18: e59ff1fc  ldr pc, [pc, #508] ; 0x21c
      1c: e1a00000  nop   (mov r0,r0)


發(fā)現(xiàn) ldr pc, =handle_irq 被匯編成

   ldr pc, [pc, #508] ; 0x21c

我們又發(fā)現(xiàn)編譯器為這條指令生成了一條注釋: ; 0x21c, 它的意思是說去地址0x21c 處加載
數(shù)據(jù),怎么算的呢? 當(dāng)前地址是 0x18, 加上 508 即 0x1fc 得出 0x214,好像不是0x21c,
慢著... ARM 采用三級流水結(jié)構(gòu),那么讀 pc 時得到的得數(shù)值會是相對當(dāng)前指令的第二條指
令的地址, 即當(dāng)前地址值加上 0x8,這么算來:

  0x18 + 0x1fc + 0x8 = 0x21c

去 0x21c 處看看:

  21c: 30004208  andcc r4, r0, r8, lsl #4

是 0x30004208 這么個值,也就是說 ARM 把 0x30004208 裝進(jìn)了 pc
......


再來看看將中斷跳轉(zhuǎn)指令改成

        ldr pc, handle_irq_addr
        NOP
   handle_irq_addr: 
         .long handle_irq

也就是中斷能響應(yīng)時的反匯編代碼:

       0: ea000007  b 0x24
       4: e1a00000  nop   (mov r0,r0)
       8: e1a00000  nop   (mov r0,r0)
       c: e1a00000  nop   (mov r0,r0)
      10: e1a00000  nop   (mov r0,r0)
      14: e1a00000  nop   (mov r0,r0)
      18: e59ff000  ldr pc, [pc, #0] ; 0x20
      1c: e1a00000  nop   (mov r0,r0)

可以看到 0x18 處為      

      18: e59ff000  ldr pc, [pc, #0] ; 0x20

與上面分析同理,去 0x20 處看看:

      20: 3000420c  andcc r4, r0, ip, lsl #4

發(fā)現(xiàn) ARM 把 0x3000420c 這個數(shù)值裝進(jìn)了 pc


前后對比一下, 一個是 0x30004208, 另一個是 0x3000420c, 兩者相差 4 個字節(jié)
而后一種情況多出的4個字節(jié)是由于 定義
   
   handle_irq_addr: 
    .long handle_irq

而占用的 4 個字節(jié)。

看來編譯器忠實的匯編了代碼,那么很可能是 MMU 啟用后對 ldr pc, =handle_irq 這樣
的中斷跳轉(zhuǎn)指令產(chǎn)生了影響?

......現(xiàn)在還沒有找到合理的解釋,請高手不吝賜教

posted on 2008-01-28 11:11 Normandy 閱讀(3841) 評論(3)  編輯 收藏 引用 所屬分類: Embeded Area

評論

# re: s3c2410 MMU 啟用后設(shè)置中斷跳轉(zhuǎn)指令遇到的問題  回復(fù)  更多評論   

樓主其實已經(jīng)摸到錯誤的門了,雖然沒能得出結(jié)論…………
2008-01-28 14:36 | ggyy

# re: s3c2410 MMU 啟用后設(shè)置中斷跳轉(zhuǎn)指令遇到的問題  回復(fù)  更多評論   

@ggyy

呵呵,問題已經(jīng)解決,一個低級的錯誤,原因如下:
508 + 0x8 即 516, 大于 512, 前面我提到把 Nand flash 的前 512 字節(jié)復(fù)制到 0x33ff0000 處用以設(shè)置高端中斷向量表,這樣當(dāng)發(fā)生 IRQ 中斷時,程序會去 0x33ff0000 + 508 + 0x8 處把 0x30004208 裝進(jìn) pc 并進(jìn)行跳轉(zhuǎn)來響應(yīng)中斷,但不幸的是我只復(fù)制了512字節(jié),所以 IRQ 中斷是不能響應(yīng)的。總結(jié)一下,對比上面提到的兩種設(shè)置中斷跳轉(zhuǎn)指令的方式:

(1)
b reset
NOP
NOP
NOP
NOP
NOP
ldr pc,=handle_irq
NOP

(2)
b reset
NOP
NOP
NOP
NOP
NOP
ldr pc, handle_irq_addr
NOP
handle_irq_addr:
.long handle_irq

第二種方式的好處是顯而易見的,只需要偏移 0x8 就能取到目的地址了;對第一種方式,ARM 要去通過一個偏移來取到目的地址,具體數(shù)值要看編譯如何設(shè)置了。
2008-01-29 14:00 | Normandy

# re: s3c2410 MMU 啟用后設(shè)置中斷跳轉(zhuǎn)指令遇到的問題  回復(fù)  更多評論   

其實,ARM匯編指令LDR很好的說明了這個問題,看看它的說明,好好理解下。
2008-11-14 17:12 | zqs
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            最新日韩av| 亚洲在线观看视频网站| 美女主播一区| 久久久综合香蕉尹人综合网| 在线观看日韩欧美| 亚洲黄色影院| 欧美色综合网| 久久高清一区| 麻豆91精品| 这里只有精品在线播放| 在线一区亚洲| 精品99视频| 日韩一级黄色片| 国产一区二区毛片| 欧美大片在线看| 国产精品久久久久久久久婷婷 | 久久精品国产999大香线蕉| 一区二区三区在线观看欧美| 欧美激情a∨在线视频播放| 欧美日本在线| 欧美一级大片在线观看| 噜噜噜91成人网| 亚洲综合成人在线| 久久久亚洲国产美女国产盗摄| 亚洲人在线视频| 亚洲综合欧美日韩| 最新日韩精品| 性欧美暴力猛交69hd| 日韩视频精品在线观看| 午夜精品久久久久久| 亚洲精品乱码久久久久| 亚洲欧美国产不卡| 日韩午夜av| 久久久99久久精品女同性| 亚洲一区www| 你懂的视频一区二区| 欧美中日韩免费视频| 欧美精品免费在线| 嫩模写真一区二区三区三州| 国产精品黄页免费高清在线观看| 免费中文日韩| 国内外成人在线| 亚洲专区在线视频| 亚洲天堂av电影| 欧美精品午夜| 亚洲电影成人| 亚洲成色www久久网站| 亚洲欧美在线一区| 亚洲女同精品视频| 欧美日韩免费一区| 亚洲精品国精品久久99热一| 亚洲大片在线| 久久久亚洲国产天美传媒修理工| 久久精品91久久香蕉加勒比| 国产精品福利在线观看| 最新国产乱人伦偷精品免费网站 | 亚洲精品国产欧美| 久久久精品国产免大香伊 | 久久aⅴ国产欧美74aaa| 欧美亚日韩国产aⅴ精品中极品| 欧美国产三级| 亚洲电影免费观看高清完整版| 欧美有码视频| 久久综合久久久久88| 国产一区二区你懂的| 亚洲欧美日韩精品久久久久| 欧美亚洲一区二区三区| 国产老女人精品毛片久久| 亚洲欧美国产视频| 久久久av网站| 精品成人国产在线观看男人呻吟| 久久大逼视频| 免费不卡视频| 亚洲人成网在线播放| 欧美久久久久| 亚洲一级在线观看| 久久精品国产视频| 1000精品久久久久久久久| 免费亚洲电影在线观看| 亚洲人成网站色ww在线| 亚洲与欧洲av电影| 国产亚洲一区精品| 久久久综合网站| 亚洲精品一区二| 亚洲欧美国产精品专区久久| 国产精品外国| 久久中文在线| 夜夜嗨一区二区| 久久理论片午夜琪琪电影网| 亚洲欧洲日产国产综合网| 欧美日韩精品福利| 欧美一区亚洲| 亚洲人成亚洲人成在线观看图片 | 亚洲在线一区二区| 国产亚洲成年网址在线观看| 麻豆视频一区二区| 中国日韩欧美久久久久久久久| 欧美制服丝袜| 亚洲精品社区| 国产亚洲欧洲| 欧美日韩一区二区在线播放| 久久国产精品99国产精| 亚洲精品一二三| 久久久久九九九九| 一区二区三欧美| 在线播放豆国产99亚洲| 欧美午夜剧场| 久久综合九色综合欧美就去吻| 亚洲天堂网在线观看| 欧美激情亚洲综合一区| 欧美在线观看网站| 亚洲视频电影图片偷拍一区| 在线国产精品播放| 国产日韩精品一区观看| 欧美日韩国产精品自在自线| 久久精品国产欧美激情| 亚洲一区久久久| 日韩系列在线| 最近中文字幕mv在线一区二区三区四区| 性高湖久久久久久久久| 一区二区三区国产盗摄| 亚洲狠狠婷婷| 国语自产精品视频在线看抢先版结局 | 久久精品1区| 亚洲一区视频在线| 日韩一级二级三级| 亚洲国产高清高潮精品美女| 国产日韩在线一区| 国产精品一二三四| 欧美色欧美亚洲高清在线视频| 毛片一区二区三区| 久久一区二区精品| 久久精品视频99| 欧美一区二区免费| 亚洲欧美日韩网| 亚洲线精品一区二区三区八戒| 91久久中文| 亚洲精品日韩精品| 亚洲欧洲精品一区二区三区| 免费看av成人| 欧美成人午夜激情| 欧美激情视频网站| 亚洲国产精品福利| 亚洲国产高清在线观看视频| 欧美国产成人在线| 亚洲国产mv| 91久久一区二区| 日韩一级黄色av| 亚洲一区二区视频在线观看| 亚洲欧美日韩国产中文| 欧美在线观看视频| 久久亚洲精品视频| 欧美大色视频| 欧美四级剧情无删版影片| 欧美午夜电影在线观看| 国产精品一区二区三区四区| 国产亚洲成精品久久| 激情综合久久| 亚洲精品美女在线观看| 亚洲视频专区在线| 欧美在线观看一二区| 久久婷婷国产综合精品青草| 欧美寡妇偷汉性猛交| 日韩视频免费观看| 亚洲欧洲99久久| 两个人的视频www国产精品| 欧美精品激情在线观看| 国产精品视频导航| 在线精品一区| 99精品欧美一区二区三区综合在线| 国产精品99久久久久久宅男| 亚洲欧美日韩精品久久奇米色影视| 久久精品免费观看| 亚洲激情第一区| 午夜一区二区三区不卡视频| 免费欧美视频| 国产伦理一区| 日韩西西人体444www| 欧美在线免费视屏| 91久久精品日日躁夜夜躁欧美| 亚洲免费影视| 欧美激情按摩在线| 狠狠操狠狠色综合网| 亚洲深夜福利| 欧美电影免费观看高清| 亚洲一区二区视频| 欧美二区在线观看| 很黄很黄激情成人| 亚洲一区二区三区在线播放| 麻豆精品视频在线观看视频| av成人毛片| 欧美国产一区在线| 好吊色欧美一区二区三区视频| 亚洲先锋成人| 亚洲激情视频在线播放| 久久精品av麻豆的观看方式| 国产精品美女久久久| 99精品视频一区二区三区| 久久综合中文字幕| 香蕉久久精品日日躁夜夜躁|