Subversion Repositories Kolibri OS

Rev

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