Subversion Repositories Kolibri OS

Rev

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