Subversion Repositories Kolibri OS

Rev

Rev 2010 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2007-2008. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. IRQ_RESERVE = 24        ; 16 or 24
  9.  
  10. iglobal
  11. IRQ_COUNT       dd      16
  12. endg
  13.  
  14. uglobal
  15. APIC:           dd      0
  16. LAPIC_BASE:     dd      0
  17. IOAPIC_base:    dd      0
  18. endg
  19.  
  20. APIC_ID         equ     0x20
  21. APIC_TPR        equ     0x80
  22. APIC_EOI        equ     0xb0
  23. APIC_LDR        equ     0xd0
  24. APIC_DFR        equ     0xe0
  25. APIC_SVR        equ     0xf0
  26. APIC_ISR        equ     0x100
  27. APIC_ESR        equ     0x280
  28. APIC_ICRL       equ     0x300
  29. APIC_ICRH       equ     0x310
  30. APIC_LVT_LINT0  equ     0x350
  31. APIC_LVT_LINT1  equ     0x360
  32. APIC_LVT_err    equ     0x370
  33.  
  34. ; APIC timer
  35. APIC_LVT_timer  equ     0x320
  36. APIC_timer_div  equ     0x3e0
  37. APIC_timer_init equ     0x380
  38. APIC_timer_cur  equ     0x390
  39. ; IOAPIC
  40. IOAPIC_ID       equ     0x0
  41. IOAPIC_VER      equ     0x1
  42. IOAPIC_ARB      equ     0x2
  43. IOAPIC_REDTBL   equ     0x10
  44.  
  45. APIC_init:
  46.         mov     dword[APIC], 0
  47.         ; jmp   .no_apic                ; NO APIC
  48.         bt      [cpu_caps], CAPS_APIC
  49.         jnc     .no_apic
  50.         ; Check for MP table
  51.         ;.....
  52.        
  53.         call    IRQ_mask_all
  54.        
  55.         ; IOAPIC init
  56.         ; 0xfec00000 - may be relocated, see chip reference... & MP table
  57.         stdcall map_io_mem, 0xfec00000, 0x20, PG_SW
  58.         mov     [IOAPIC_base], eax
  59.        
  60.         mov     eax, IOAPIC_VER
  61.         call    IOAPIC_read
  62.         shr     eax, 16
  63.         inc     al
  64.         movzx   eax, al
  65.         cmp     al, IRQ_RESERVE
  66.         jbe     @f
  67.         mov     al, IRQ_RESERVE
  68. @@:     mov     [IRQ_COUNT], eax
  69.  
  70.         ; Reroute IOAPIC & mask all interrupts
  71.         xor     ecx, ecx
  72.         mov     eax, IOAPIC_REDTBL
  73. @@:     mov     ebx, eax
  74.         call    IOAPIC_read
  75.         mov     ah, 0x09                ; Delivery Mode: Lowest Priority, Destination Mode: Logical
  76.         mov     al, cl
  77.         add     al, 0x20                ; vector
  78.         or      eax, 0x10000            ; Mask Interrupt
  79.         cmp     ecx, 16
  80.         jb      .set
  81.         or      eax, 0xa000             ;<<< level-triggered active-low for IRQ16+
  82. .set:
  83.         xchg    eax, ebx
  84.         call    IOAPIC_write
  85.         inc     eax
  86.         mov     ebx, eax
  87.         call    IOAPIC_read
  88.         or      eax, 0xff000000         ; Destination Field
  89.         xchg    eax, ebx
  90.         call    IOAPIC_write
  91.         inc     eax
  92.         inc     ecx
  93.         cmp     ecx, [IRQ_COUNT]
  94.         jb      @b
  95.  
  96.         call    LAPIC_init
  97.        
  98.         mov     dword[APIC], 0xffffffff
  99.         ; mov   dword[irq_type_to_set], IRQ_TYPE_APIC
  100. .no_apic:
  101.         ret
  102.        
  103. ;===========================================================
  104. align 4
  105. LAPIC_init:
  106.         ; Check MSR support
  107.         ;....
  108.         ; Get LAPIC base address
  109.         mov     ecx, 0x1b
  110.         rdmsr                           ; it may be replaced to
  111.         and     ax, 0xf000              ; mov   eax, 0xfee00000
  112.        
  113.         stdcall map_io_mem, eax, 0x1000, PG_SW
  114.         mov     [LAPIC_BASE], eax
  115.         mov     esi, eax
  116.        
  117.         ; Program Destination Format Register for Flat mode.
  118.         mov     eax, [esi + APIC_DFR]
  119.         or      eax, 0xf0000000
  120.         mov     [esi + APIC_DFR], eax
  121.        
  122.        
  123.         ; Program Logical Destination Register.
  124.         mov     eax, [esi + APIC_LDR]
  125.         ;and    eax, 0xff000000
  126.         and     eax, 0x00ffffff
  127.         or      eax, 0x01000000 ;!!!!!!!!!!!!
  128.         mov     [esi + APIC_LDR], eax
  129.        
  130.         ; Task Priority Register initialization.
  131.         mov     eax, [esi + APIC_TPR]
  132.         and     eax, 0xffffff00
  133.         mov     [esi + APIC_TPR], eax
  134.  
  135.         ; Flush the queue
  136.         mov     edx, 0
  137. .nxt2:  mov     ecx, 32
  138.         mov     eax, [esi + APIC_ISR + edx]
  139. .nxt:   shr     eax, 1
  140.         jnc     @f
  141.         mov     dword [esi + APIC_EOI], 0       ; EOI
  142. @@:     loop    .nxt
  143.         add     edx, 0x10
  144.         cmp     edx, 0x170
  145.         jbe     .nxt2
  146.  
  147.         ; Spurious-Interrupt Vector Register initialization.
  148.         mov     eax, [esi + APIC_SVR]
  149.         or      eax, 0x1ff
  150.         and     eax, 0xfffffdff
  151.         mov     [esi + APIC_SVR], eax
  152.  
  153.         ; Initialize LVT LINT0 register. (INTR)
  154.         mov     eax, 0x00700
  155.         ; mov   eax, 0x10700
  156.         mov     [esi + APIC_LVT_LINT0], eax
  157.  
  158.         ; Initialize LVT LINT1 register. (NMI)
  159.         mov     eax, 0x00400
  160.         mov     [esi + APIC_LVT_LINT1], eax
  161.  
  162.         ; Initialize LVT Error register.
  163.         mov     eax, [esi + APIC_LVT_err]
  164.         or      eax, 0x10000            ; bit 16
  165.         mov     [esi + APIC_LVT_err], eax
  166.        
  167.         ; LAPIC timer
  168.         ; pre init
  169.         mov     dword[esi + APIC_timer_div], 1011b      ; 1
  170.         mov     dword[esi + APIC_timer_init], 0xffffffff        ; max val
  171.         push    esi
  172.         mov     esi, 640                                ; wait 0.64 sec
  173.         call    delay_ms
  174.         pop     esi
  175.         mov     eax, [esi + APIC_timer_cur]             ; read current tick couner
  176.         xor     eax, 0xffffffff                         ; eax = 0xffffffff - eax
  177.         shr     eax, 6                                  ; eax /= 64; APIC ticks per 0.01 sec
  178.        
  179.         ; Start (every 0.01 sec)
  180.         mov     dword[esi + APIC_LVT_timer], 0x30020    ; periodic int 0x20
  181.         mov     dword[esi + APIC_timer_init], eax
  182.        
  183.         ret
  184. ;===========================================================
  185. ; IOAPIC implementation
  186. align 4
  187. IOAPIC_read:
  188. ; in : EAX - IOAPIC register
  189. ; out: EAX - readed value
  190.         push    esi
  191.         mov     esi, [IOAPIC_base]
  192.         mov     [esi], eax
  193.         mov     eax, [esi + 0x10]
  194.         pop     esi
  195.         ret
  196. align 4
  197. IOAPIC_write:
  198. ; in :  EAX - IOAPIC register
  199. ;       EBX - value
  200. ; out:  none
  201.         push    esi
  202.         mov     esi, [IOAPIC_base]
  203.         mov     [esi], eax
  204.         mov     [esi + 0x10], ebx
  205.         pop     esi
  206.         ret
  207. ;===========================================================
  208. ; Remap all IRQ to 0x20+ Vectors
  209. ; IRQ0 to vector 0x20, IRQ1 to vector 0x21....
  210. PIC_init:
  211.         cli
  212.         mov     al,0x11         ;  icw4, edge triggered
  213.         out     0x20,al
  214.         call    pic_delay
  215.         out     0xA0,al
  216.         call    pic_delay
  217.  
  218.         mov     al,0x20         ;  generate 0x20 +
  219.         out     0x21,al
  220.         call    pic_delay
  221.         mov     al,0x28         ;  generate 0x28 +
  222.         out     0xA1,al
  223.         call    pic_delay
  224.  
  225.         mov     al,0x04         ;  slave at irq2
  226.         out     0x21,al
  227.         call    pic_delay
  228.         mov     al,0x02         ;  at irq9
  229.         out     0xA1,al
  230.         call    pic_delay
  231.  
  232.         mov     al,0x01         ;  8086 mode
  233.         out     0x21,al
  234.         call    pic_delay
  235.         out     0xA1,al
  236.         call    pic_delay
  237.  
  238.         call    IRQ_mask_all
  239.         cli
  240.         ; mov   dword[irq_type_to_set], IRQ_TYPE_PIC
  241.         ret
  242.  
  243. ; -----------------------------------------
  244. pic_delay:
  245.         jmp     pdl1
  246. pdl1:   ret
  247.  
  248. ; -----------------------------------------
  249. ; TIMER SET TO 1/100 S
  250. PIT_init:
  251.         mov   al,0x34              ; set to 100Hz
  252.         out   0x43,al
  253.         mov   al,0x9b              ; lsb    1193180 / 1193
  254.         out   0x40,al
  255.         mov   al,0x2e              ; msb
  256.         out   0x40,al
  257.         ret
  258.  
  259. ; -----------------------------------------
  260. unmask_timer:
  261.         test    dword[APIC], 0xffffffff
  262.         jnz     @f
  263.         stdcall enable_irq, 0
  264.         ret
  265. @@:    
  266.         ; use PIT
  267.         ; in some systems PIT no connected to IOAPIC
  268.         ; mov   eax, 0x14
  269.         ; call  IOAPIC_read
  270.         ; mov   ah, 0x09                ; Delivery Mode: Lowest Priority, Destination Mode: Logical
  271.         ; mov   al, 0x20
  272.         ; or    eax, 0x10000            ; Mask Interrupt
  273.         ; mov   ebx, eax
  274.         ; mov   eax, 0x14
  275.         ; call  IOAPIC_write
  276.         ; stdcall enable_irq, 2
  277.         ; ret
  278.        
  279.         ; use LAPIC timer
  280.         mov     esi, [LAPIC_BASE]
  281.         mov     eax, [esi + APIC_LVT_timer]
  282.         and     eax, 0xfffeffff
  283.         mov     [esi + APIC_LVT_timer], eax
  284.         ret
  285.  
  286. ; -----------------------------------------
  287. ; Disable all IRQ
  288. IRQ_mask_all:
  289.         test    dword[APIC], 0xffffffff
  290.         jnz     .APIC
  291.         mov     al, 0xFF
  292.         out     0x21, al
  293.         out     0xA1, al
  294.         mov     ecx,0x1000
  295.         cld
  296. @@:     call    pic_delay
  297.         loop    @b
  298.         ret
  299. .APIC:
  300.         mov     ecx, [IRQ_COUNT]
  301.         mov     eax, 0x10
  302. @@:     mov     ebx, eax
  303.         call    IOAPIC_read
  304.         or      eax, 0x10000            ; bit 16
  305.         xchg    eax, ebx
  306.         call    IOAPIC_write
  307.         inc     eax
  308.         inc     eax
  309.         loop    @b
  310.         ret
  311. ; -----------------------------------------
  312. ; End Of Interrupt
  313. ; al - IRQ number
  314. align 16
  315. IRQ_EOI:
  316.         test    dword[APIC], 0xffffffff
  317.         jnz     .APIC
  318.         cmp     al, 8
  319.         mov     al, 0x20
  320.         jb      @f
  321.         out     0xa0, al
  322. @@:     out     0x20, al
  323.         ret
  324. .APIC: 
  325.         mov     eax, [LAPIC_BASE]
  326.         mov     dword [eax + APIC_EOI], 0       ; EOI
  327.         ret
  328.        
  329. ; -----------------------------------------
  330. ; from dll.inc
  331. align 4
  332. proc enable_irq stdcall, irq_line:dword
  333.         mov     ebx, [irq_line]
  334.         test    dword[APIC], 0xffffffff
  335.         jnz     .APIC
  336.         mov     edx, 0x21
  337.         cmp     ebx, 8
  338.         jb      @F
  339.         mov     edx, 0xA1
  340.         sub     ebx,8
  341. @@:
  342.         in      al,dx
  343.         btr     eax, ebx
  344.         out     dx, al
  345.         ret
  346. .APIC:
  347.         shl     ebx, 1
  348.         add     ebx, 0x10
  349.         mov     eax, ebx
  350.         call    IOAPIC_read
  351.         and     eax, 0xfffeffff         ; bit 16
  352.         xchg    eax, ebx
  353.         call    IOAPIC_write
  354.         ret
  355. endp
  356.  
  357.  
  358.  
  359. ; IRQ_TYPE_DISABLE      equ     0
  360. ; IRQ_TYPE_PIC          equ     1
  361. ; IRQ_TYPE_APIC         equ     2
  362.  
  363. ; uglobal
  364. ; irq_type_to_set       rd      1
  365. ; irq_types     rd      IRQ_RESERVE
  366. ; endg
  367.  
  368. ; -----------------------------------------
  369. ; End Of Interrupt
  370. ; al - IRQ number
  371. ; align 16
  372. ; IRQ_EOI:
  373.         ; movzx eax, al
  374.         ; cmp   dword[irq_types + eax * 4], IRQ_TYPE_APIC
  375.         ; jne   @f
  376.         ; mov   eax, [LAPIC_BASE]
  377.         ; mov   dword [eax + APIC_EOI], 0       ; EOI
  378.         ; ret
  379. ; @@:
  380.         ; cmp   al, 8
  381.         ; mov   al, 0x20
  382.         ; jb    @f
  383.         ; out   0xa0, al
  384. ; @@:   out     0x20, al
  385.         ; ret
  386.  
  387. ; align 4
  388. ; proc enable_irq stdcall, irq_line:dword
  389.         ; cmp   dword[irq_type_to_set], IRQ_TYPE_APIC
  390.         ; jne   @f
  391.         ; stdcall       APIC_enable_irq, [irq_line]
  392.         ; ret
  393. ; @@:   stdcall PIC_enable_irq, [irq_line]
  394.         ; ret
  395. ; endp
  396.  
  397. ; align 4
  398. ; proc disable_irq stdcall, irq_line:dword
  399.         ; push  eax
  400.         ; mov   eax, [irq_line]
  401.         ; cmp   dword[irq_types + eax * 4], IRQ_TYPE_APIC
  402.         ; jne   @f
  403.         ; stdcall       APIC_disable_irq, eax
  404.         ; pop   eax
  405.         ; ret
  406. ; @@:   stdcall PIC_disable_irq, eax
  407.         ; pop   eax
  408.         ; ret
  409. ; endp
  410.  
  411. ; align 4
  412. ; proc PIC_enable_irq stdcall, irq_line:dword
  413.         ; pusha
  414.         ; mov   ebx, [irq_line]
  415.         ; mov   eax, [irq_types + ebx * 4]
  416.         ; cmp   eax, IRQ_TYPE_DISABLE
  417.         ; je    @f
  418.         ; cmp   eax, IRQ_TYPE_PIC
  419.         ; je    @f
  420.         ; stdcall       disable_irq, ebx
  421. ; @@:   mov     dword[irq_types + ebx * 4], IRQ_TYPE_PIC
  422.         ; mov   edx, 0x21
  423.         ; cmp   ebx, 8
  424.         ; jb    @F
  425.         ; mov   edx, 0xA1
  426.         ; sub   ebx,8
  427. ; @@:   in      al,dx
  428.         ; btr   eax, ebx
  429.         ; out   dx, al
  430.         ; popa
  431.         ; ret
  432. ; endp
  433.  
  434. ; align 4
  435. ; proc PIC_disable_irq stdcall, irq_line:dword
  436.         ; pusha
  437.         ; mov   ebx, [irq_line]
  438.         ; mov   dword[irq_types + ebx * 4], IRQ_TYPE_DISABLE
  439.         ; mov   edx, 0x21
  440.         ; cmp   ebx, 8
  441.         ; jb    @F
  442.         ; mov   edx, 0xA1
  443.         ; sub   ebx,8
  444. ; @@:   in      al,dx
  445.         ; bts   eax, ebx
  446.         ; out   dx, al
  447.         ; popa
  448.         ; ret
  449. ; endp
  450.  
  451. ; align 4
  452. ; proc APIC_enable_irq stdcall, irq_line:dword
  453.         ; pusha
  454.         ; mov   ebx, [irq_line]
  455.         ; mov   eax, [irq_types + ebx * 4]
  456.         ; cmp   eax, IRQ_TYPE_DISABLE
  457.         ; je    @f
  458.         ; cmp   eax, IRQ_TYPE_APIC
  459.         ; je    @f
  460.         ; stdcall       disable_irq, ebx
  461. ; @@:   mov     dword[irq_types + ebx * 4], IRQ_TYPE_APIC
  462.         ; shl   ebx, 1
  463.         ; add   ebx, 0x10
  464.         ; mov   eax, ebx
  465.         ; call  IOAPIC_read
  466.         ; and   eax, 0xfffeffff         ; bit 16
  467.         ; xchg  eax, ebx
  468.         ; call  IOAPIC_write
  469.         ; popa
  470.         ; ret
  471. ; endp
  472.  
  473. ; align 4
  474. ; proc APIC_disable_irq stdcall, irq_line:dword
  475.         ; pusha
  476.         ; mov   ebx, [irq_line]
  477.         ; mov   dword[irq_types + ebx * 4], IRQ_TYPE_DISABLE
  478.         ; shl   ebx, 1
  479.         ; add   ebx, 0x10
  480.         ; mov   eax, ebx
  481.         ; call  IOAPIC_read
  482.         ; or    eax, 0x10000
  483.         ; xchg  eax, ebx
  484.         ; call  IOAPIC_write
  485.         ; popa
  486.         ; ret
  487. ; endp
  488.