Subversion Repositories Kolibri OS

Rev

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