Subversion Repositories Kolibri OS

Rev

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

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