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

隨筆 - 60, 文章 - 0, 評論 - 197, 引用 - 0
數據加載中……

s3c2410 MMU 啟用后設置中斷跳轉指令遇到的問題

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

MMU 啟用后中斷不能響應了!, 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 放入一條長跳轉指 ldr pc, =handle_irq 來響應中斷的,在
沒有啟用 MMU 之前,代碼工作的很好。通過如下兩個函數啟用了 MMU 實現虛擬內存管理:

     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, 可以看到:
通過設置頁表,將 0xffff0000 為首地址的 32 個字節的中斷向量表被映射到 0x33ff0000 為首地址的 32 字節區域,

既然設置了高端中斷向量,我們就要在 0x33ff0000 處設置中斷跳轉指令,通過調用下面這個函數:

   bl  flash_to_sdram

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

如何讓 ARM 使用高端的中斷跳轉指令呢?通過設置 CP15 協處理器的一些寄存器來啟用。以下是內聯匯編片段

   /*
    * 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"

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

......經過了一天的折騰,發現將中斷跳轉指令由
   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


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

        ldr pc, handle_irq_addr
        NOP
   handle_irq_addr: 
        .long handle_irq

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

#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;
}

代碼將數據通過串口在超級終端上進行顯示后,發現確有微妙不同:

中斷不能響應時(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


中斷可以響應時(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


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

中斷不能響應時(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)


發現 ldr pc, =handle_irq 被匯編成

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

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

  0x18 + 0x1fc + 0x8 = 0x21c

去 0x21c 處看看:

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

是 0x30004208 這么個值,也就是說 ARM 把 0x30004208 裝進了 pc
......


再來看看將中斷跳轉指令改成

        ldr pc, handle_irq_addr
        NOP
   handle_irq_addr: 
         .long handle_irq

也就是中斷能響應時的反匯編代碼:

       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

發現 ARM 把 0x3000420c 這個數值裝進了 pc


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

而占用的 4 個字節。

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

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

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

評論

# re: s3c2410 MMU 啟用后設置中斷跳轉指令遇到的問題  回復  更多評論   

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

# re: s3c2410 MMU 啟用后設置中斷跳轉指令遇到的問題  回復  更多評論   

@ggyy

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

(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 要去通過一個偏移來取到目的地址,具體數值要看編譯如何設置了。
2008-01-29 14:00 | Normandy

# re: s3c2410 MMU 啟用后設置中斷跳轉指令遇到的問題  回復  更多評論   

其實,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>
            欧美激情网友自拍| 一区二区三区免费在线观看| 精品成人一区| 国产精品亚洲一区二区三区在线| 欧美精品三级日韩久久| 欧美大片在线观看一区| 欧美高清自拍一区| 欧美日韩国产精品成人| 国产精品国产成人国产三级| 欧美三级黄美女| 国产精品日韩精品欧美在线| 国产欧美欧美| 海角社区69精品视频| 亚洲精选中文字幕| 国产亚洲精品v| 国产精品亚洲综合久久| 国产午夜精品全部视频播放| 国语自产精品视频在线看| 亚洲第一二三四五区| 亚洲精品在线观看视频| 亚洲专区国产精品| 久久天天躁夜夜躁狠狠躁2022| 玖玖国产精品视频| 亚洲精品久久久久中文字幕欢迎你| 欧美激情导航| 亚洲一级二级| 另类图片国产| 国产精品亚洲视频| 最新热久久免费视频| 亚洲一区二区三区成人在线视频精品 | 国产伦精品一区二区三区| 国语自产精品视频在线看抢先版结局| 亚洲激情影院| 久久精品国产亚洲一区二区| 亚洲福利电影| 欧美亚洲专区| 欧美视频在线观看一区二区| 亚洲国产精品va在线观看黑人| 欧美亚洲系列| 99精品国产热久久91蜜凸| 久久午夜色播影院免费高清| 国产精品高潮呻吟久久av无限 | 国产精品亚洲综合| 日韩一级网站| 欧美国产欧美亚洲国产日韩mv天天看完整| 一区二区激情| 欧美连裤袜在线视频| 在线观看国产成人av片| 午夜精品一区二区在线观看| 91久久精品国产| 另类天堂av| 在线观看91久久久久久| 久久精品一本| 午夜视频在线观看一区二区三区 | 亚洲欧美综合国产精品一区| 欧美日韩国产成人精品| 亚洲国产一二三| 狼狼综合久久久久综合网| 亚洲网站在线| 欧美三级第一页| 99re在线精品| 亚洲精品在线免费| 欧美欧美全黄| 日韩一区二区免费高清| 最新日韩欧美| 欧美精品久久久久a| 亚洲欧美国产77777| 亚洲人成人77777线观看| 久色成人在线| 久久天天躁狠狠躁夜夜爽蜜月| 国产欧美一区二区三区沐欲| 欧美一区二区成人| 午夜伦欧美伦电影理论片| 国产精品一区亚洲| 欧美一区二区视频97| 午夜精品久久99蜜桃的功能介绍| 国产精品天美传媒入口| 欧美在线亚洲一区| 久久久精彩视频| 亚洲国产天堂久久综合| 亚洲日本视频| 国产精品久久久久久模特| 久久精品国产第一区二区三区最新章节 | 亚洲国产成人在线播放| 欧美国产日韩xxxxx| 欧美日韩免费观看一区三区| 亚洲一区视频| 久久激情五月激情| 亚洲区免费影片| 一区二区毛片| 极品裸体白嫩激情啪啪国产精品| 亚洲大黄网站| 国产精品区一区二区三| 浪潮色综合久久天堂| 欧美精品一区二区精品网| 亚洲欧美日韩在线不卡| 欧美在线影院| 日韩亚洲精品视频| 亚洲一区免费观看| 亚洲国产综合在线看不卡| 一本色道久久88综合日韩精品| 国产一区二区三区在线免费观看| 亚洲国产精品悠悠久久琪琪| 国产精品成人一区二区网站软件| 久久这里只有| 国产精品户外野外| 欧美激情一区| 国模 一区 二区 三区| 亚洲精品日韩在线观看| 国内精品久久国产| 一区二区欧美激情| 亚洲精品视频在线| 久久精品女人| 性刺激综合网| 欧美日韩另类一区| 美女网站在线免费欧美精品| 欧美色大人视频| 亚洲国产va精品久久久不卡综合| 国产欧美精品一区| 亚洲网址在线| 亚洲综合大片69999| 欧美欧美天天天天操| 久久久国产午夜精品| 亚洲无线一线二线三线区别av| 久久深夜福利免费观看| 久久久www免费人成黑人精品 | 国产亚洲欧美一区| 亚洲午夜一级| 亚洲一区三区电影在线观看| 欧美激情片在线观看| 欧美福利电影网| 在线国产亚洲欧美| 校园激情久久| 久久精品99国产精品| 国产精品一区三区| 亚洲欧美激情一区二区| 亚洲欧美综合国产精品一区| 欧美日韩一二三区| 99这里只有久久精品视频| 久久亚洲美女| 蜜臀av一级做a爰片久久 | 尤物网精品视频| 亚洲激情视频| 国产视频欧美视频| 亚洲欧美日韩国产中文在线| 亚洲毛片在线观看| 久久综合狠狠综合久久激情| 国产一区二区无遮挡| 亚洲综合国产激情另类一区| 一本久久知道综合久久| 久久中文欧美| 老司机一区二区三区| 18成人免费观看视频| 亚洲欧美中文另类| 欧美一区二区三区四区在线| 欧美小视频在线观看| 久久婷婷麻豆| 亚洲精品一区二区网址| 久久这里只有精品视频首页| 久久综合一区二区| 在线播放国产一区中文字幕剧情欧美 | 午夜欧美理论片| 欧美搞黄网站| 亚洲午夜久久久久久尤物 | 欧美第一黄色网| 亚洲国产高清在线| 久久综合九九| 亚洲电影免费观看高清完整版| 亚洲国产欧美日韩精品| 欧美尤物一区| 另类欧美日韩国产在线| 亚洲国产精品久久久久秋霞影院| 久久综合九色九九| 久久精品女人| 一本到高清视频免费精品| 欧美手机在线| 欧美亚洲一区二区三区| 亚洲午夜女主播在线直播| 在线播放豆国产99亚洲| 久久久av毛片精品| 性伦欧美刺激片在线观看| 精品粉嫩aⅴ一区二区三区四区| 久久精品国语| 91久久国产精品91久久性色| 一本色道久久综合精品竹菊| 国产精品一区久久久| 久久国产精品久久久| 欧美黄色大片网站| 在线一区视频| 亚洲国产精品嫩草影院| 欧美日韩黄色大片| 亚洲图片自拍偷拍| 美女视频黄免费的久久| 一区二区日韩伦理片| 国产日韩精品综合网站| 欧美精品97| 欧美一区二区视频网站| 欧美福利电影网| 亚洲免费在线| 一区二区三区高清在线 |