Subversion Repositories Kolibri OS

Rev

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