Subversion Repositories Kolibri OS

Rev

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