Subversion Repositories Kolibri OS

Rev

Rev 5565 | Rev 5645 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 4850 $
  9.  
  10.  
  11. iglobal
  12. IRQ_COUNT    dd 24
  13. endg
  14.  
  15. uglobal
  16. irq_mode     rd  1
  17. IOAPIC_base  rd  1
  18. LAPIC_BASE   rd  1
  19. endg
  20.  
  21. APIC_ID         equ 0x20
  22. APIC_TPR       equ 0x80
  23. APIC_EOI       equ 0xb0
  24. APIC_LDR       equ 0xd0
  25. APIC_DFR       equ 0xe0
  26. APIC_SVR       equ 0xf0
  27. APIC_ISR       equ 0x100
  28. APIC_ESR       equ 0x280
  29. APIC_ICRL       equ 0x300
  30. APIC_ICRH       equ 0x310
  31. APIC_LVT_LINT0 equ 0x350
  32. APIC_LVT_LINT1 equ 0x360
  33. APIC_LVT_err   equ 0x370
  34.  
  35. ; APIC timer
  36. APIC_LVT_timer equ 0x320
  37. APIC_timer_div equ 0x3e0
  38. APIC_timer_init equ 0x380
  39. APIC_timer_cur equ 0x390
  40. ; IOAPIC
  41. IOAPIC_ID       equ 0x0
  42. IOAPIC_VER     equ 0x1
  43. IOAPIC_ARB     equ 0x2
  44. IOAPIC_REDTBL   equ 0x10
  45.  
  46. align 4
  47. APIC_init:
  48.         mov     [irq_mode], IRQ_PIC
  49.  
  50.         cmp     [acpi_ioapic_base], 0
  51.         jz      .no_apic
  52.  
  53.         cmp     [acpi_lapic_base], 0
  54.         jz      .no_apic
  55.  
  56.         stdcall load_file, dev_data_path
  57.         test    eax, eax
  58.         jz      .no_apic
  59.  
  60.         mov     [acpi_dev_data], eax
  61.         mov     [acpi_dev_size], ebx
  62.  
  63.         call    IRQ_mask_all
  64.  
  65. ; IOAPIC init
  66.         stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_GLOBAL+PG_NOCACHE+PG_SWR
  67.         mov     [IOAPIC_base], eax
  68.  
  69.         mov     eax, IOAPIC_VER
  70.         call    IOAPIC_read
  71.         shr     eax, 16
  72.         inc     al
  73.         movzx   eax, al
  74.         cmp     al, IRQ_RESERVED
  75.         jbe     @f
  76.  
  77.         mov     al, IRQ_RESERVED
  78. @@:
  79.         mov     [IRQ_COUNT], eax
  80.  
  81.         ; Reroute IOAPIC & mask all interrupts
  82.         xor     ecx, ecx
  83.         mov     eax, IOAPIC_REDTBL
  84. @@:
  85.         mov     ebx, eax
  86.         call    IOAPIC_read
  87.         mov     ah, 0x08; Delivery Mode: Fixed, Destination Mode: Logical
  88.         mov     al, cl
  89.         add     al, 0x20; vector
  90.         or      eax, 0x10000; Mask Interrupt
  91.         cmp     ecx, 16
  92.         jb      .set
  93.  
  94.         or      eax, 0xa000;<<< level-triggered active-low for IRQ16+
  95. .set:
  96.         xchg    eax, ebx
  97.         call    IOAPIC_write
  98.         inc     eax
  99.         mov     ebx, eax
  100.         call    IOAPIC_read
  101.         or      eax, 0xff000000; Destination Field
  102.         xchg    eax, ebx
  103.         call    IOAPIC_write
  104.         inc     eax
  105.         inc     ecx
  106.         cmp     ecx, [IRQ_COUNT]
  107.         jb      @b
  108.  
  109.         call    LAPIC_init
  110.  
  111.         mov     [irq_mode], IRQ_APIC
  112.  
  113.         mov     al, 0x70
  114.         out     0x22, al
  115.         mov     al, 1
  116.         out     0x23, al
  117.  
  118.         call    pci_irq_fixup
  119. .no_apic:
  120.  
  121.         ret
  122.  
  123. ;===========================================================
  124. align 4
  125. LAPIC_init:
  126.  
  127.         cmp     [LAPIC_BASE], 0
  128.         jne     .done
  129.  
  130.         stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_GLOBAL+PG_NOCACHE+PG_SWR
  131.         mov     [LAPIC_BASE], eax
  132.         mov     esi, eax
  133.  
  134.         ; Program Destination Format Register for Flat mode.
  135.         mov     eax, [esi + APIC_DFR]
  136.         or      eax, 0xf0000000
  137.         mov     [esi + APIC_DFR], eax
  138.  
  139.         ; Program Logical Destination Register.
  140.         mov     eax, [esi + APIC_LDR]
  141.         ;and  eax, 0xff000000
  142.         and     eax, 0x00ffffff
  143.         or      eax, 0x01000000;!!!!!!!!!!!!
  144.         mov     [esi + APIC_LDR], eax
  145.  
  146.         ; Task Priority Register initialization.
  147.         mov     eax, [esi + APIC_TPR]
  148.         and     eax, 0xffffff00
  149.         mov     [esi + APIC_TPR], eax
  150.  
  151.         ; Flush the queue
  152.         mov     edx, 0
  153. .nxt2:
  154.         mov     ecx, 32
  155.         mov     eax, [esi + APIC_ISR + edx]
  156. .nxt:
  157.         shr     eax, 1
  158.         jnc     @f
  159.         mov     dword [esi + APIC_EOI], 0; EOI
  160. @@:
  161.         loop    .nxt
  162.  
  163.         add     edx, 0x10
  164.         cmp     edx, 0x170
  165.         jbe     .nxt2
  166.  
  167.         ; Spurious-Interrupt Vector Register initialization.
  168.         mov     eax, [esi + APIC_SVR]
  169.         or      eax, 0x1ff
  170.         and     eax, 0xfffffdff
  171.         mov     [esi + APIC_SVR], eax
  172.  
  173.         ; Initialize LVT LINT0 register. (INTR)
  174.         mov     eax, 0x00700
  175.         ; mov eax, 0x10700
  176.         mov     [esi + APIC_LVT_LINT0], eax
  177.  
  178.         ; Initialize LVT LINT1 register. (NMI)
  179.         mov     eax, 0x00400
  180.         mov     [esi + APIC_LVT_LINT1], eax
  181.  
  182.         ; Initialize LVT Error register.
  183.         mov     eax, [esi + APIC_LVT_err]
  184.         or      eax, 0x10000; bit 16
  185.         mov     [esi + APIC_LVT_err], eax
  186.  
  187.         ; LAPIC timer
  188.         ; pre init
  189.         mov     dword[esi + APIC_timer_div], 1011b; 1
  190.         mov     dword[esi + APIC_timer_init], 0xffffffff; max val
  191.         push    esi
  192.         mov     esi, 640    ; wait 0.64 sec
  193.         call    delay_ms
  194.         pop     esi
  195.         mov     eax, [esi + APIC_timer_cur]; read current tick couner
  196.         xor     eax, 0xffffffff   ; eax = 0xffffffff - eax
  197.         shr     eax, 6      ; eax /= 64; APIC ticks per 0.01 sec
  198.  
  199.         ; Start (every 0.01 sec)
  200.         mov     dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
  201.         mov     dword[esi + APIC_timer_init], eax
  202.  
  203. .done:
  204.         ret
  205.  
  206. ;===========================================================
  207. ; IOAPIC implementation
  208. align 4
  209. IOAPIC_read:
  210. ; in : EAX - IOAPIC register
  211. ; out: EAX - readed value
  212.         push    esi
  213.         mov     esi, [IOAPIC_base]
  214.         mov     [esi], eax
  215.         mov     eax, [esi + 0x10]
  216.         pop     esi
  217.         ret
  218.  
  219. align 4
  220. IOAPIC_write:
  221. ; in :  EAX - IOAPIC register
  222. ;       EBX - value
  223. ; out:  none
  224.         push    esi
  225.         mov     esi, [IOAPIC_base]
  226.         mov     [esi], eax
  227.         mov     [esi + 0x10], ebx
  228.         pop     esi
  229.         ret
  230. ;===========================================================
  231. ; Remap all IRQ to 0x20+ Vectors
  232. ; IRQ0 to vector 0x20, IRQ1 to vector 0x21....
  233. align 4
  234. PIC_init:
  235.         cli
  236.         mov     al, 0x11        ;  icw4, edge triggered
  237.         out     0x20, al
  238.         out     0xA0, al
  239.  
  240.         mov     al, 0x20        ;  generate 0x20 +
  241.         out     0x21, al
  242.         mov     al, 0x28        ;  generate 0x28 +
  243.         out     0xA1, al
  244.  
  245.         mov     al, 0x04        ;  slave at irq2
  246.         out     0x21, al
  247.         mov     al, 0x02        ;  at irq9
  248.         out     0xA1, al
  249.  
  250.         mov     al, 0x01        ;  8086 mode
  251.         out     0x21, al
  252.         out     0xA1, al
  253.  
  254.         call    IRQ_mask_all
  255.         ; mov   dword[irq_type_to_set], IRQ_TYPE_PIC
  256.         ret
  257.  
  258. ; -----------------------------------------
  259. ; TIMER SET TO 1/100 S
  260. align 4
  261. PIT_init:
  262.         mov     al, 0x34   ; set to 100Hz
  263.         out     0x43, al
  264.         mov     al, 0x9b   ; lsb    1193180 / 1193
  265.         out     0x40, al
  266.         mov     al, 0x2e   ; msb
  267.         out     0x40, al
  268.         ret
  269.  
  270. ; -----------------------------------------
  271. align 4
  272. unmask_timer:
  273.         cmp     [irq_mode], IRQ_APIC
  274.         je      @f
  275.  
  276.         stdcall enable_irq, 0
  277.         ret
  278. @@:
  279.         ; use PIT
  280.         ; in some systems PIT no connected to IOAPIC
  281.         ; mov   eax, 0x14
  282.         ; call  IOAPIC_read
  283.         ; mov   ah, 0x09                ; Delivery Mode: Lowest Priority, Destination Mode: Logical
  284.         ; mov   al, 0x20
  285.         ; or    eax, 0x10000            ; Mask Interrupt
  286.         ; mov   ebx, eax
  287.         ; mov   eax, 0x14
  288.         ; call  IOAPIC_write
  289.         ; stdcall enable_irq, 2
  290.         ; ret
  291.  
  292.         ; use LAPIC timer
  293.         mov     esi, [LAPIC_BASE]
  294.         mov     eax, [esi + APIC_LVT_timer]
  295.         and     eax, 0xfffeffff
  296.         mov     [esi + APIC_LVT_timer], eax
  297.         ret
  298.  
  299. ; -----------------------------------------
  300. ; Disable all IRQ
  301. align 4
  302. IRQ_mask_all:
  303.         cmp     [irq_mode], IRQ_APIC
  304.         je      .APIC
  305.  
  306.         mov     al, 0xFF
  307.         out     0x21, al
  308.         out     0xA1, al
  309.         mov     ecx, 0x1000
  310.         ret
  311. .APIC:
  312.         mov     ecx, [IRQ_COUNT]
  313.         mov     eax, 0x10
  314. @@:
  315.         mov     ebx, eax
  316.         call    IOAPIC_read
  317.         or      eax, 0x10000; bit 16
  318.         xchg    eax, ebx
  319.         call    IOAPIC_write
  320.         inc     eax
  321.         inc     eax
  322.         loop    @b
  323.         ret
  324.  
  325. ; -----------------------------------------
  326. ; End Of Interrupt
  327. ; cl - IRQ number
  328. align 4
  329. irq_eoi:         ; __fastcall
  330.         cmp     [irq_mode], IRQ_APIC
  331.         je      .APIC
  332.  
  333.         cmp     cl, 8
  334.         mov     al, 0x20
  335.         jb      @f
  336.         out     0xa0, al
  337. @@:
  338.         out     0x20, al
  339.         ret
  340.  
  341. .APIC:
  342.         mov     eax, [LAPIC_BASE]
  343.         mov     dword [eax + APIC_EOI], 0; EOI
  344.         ret
  345.  
  346. ; -----------------------------------------
  347. ; from dll.inc
  348. align 4
  349. proc enable_irq stdcall, irq_line:dword
  350.         mov     ebx, [irq_line]
  351.         cmp     [irq_mode], IRQ_APIC
  352.         je      .APIC
  353.  
  354.         mov     edx, 0x21
  355.         cmp     ebx, 8
  356.         jb      @F
  357.  
  358.         mov     edx, 0xA1
  359.         sub     ebx, 8
  360. @@:
  361.         in      al, dx
  362.         btr     eax, ebx
  363.         out     dx, al
  364.         ret
  365. .APIC:
  366.         shl     ebx, 1
  367.         add     ebx, 0x10
  368.         mov     eax, ebx
  369.         call    IOAPIC_read
  370.         and     eax, 0xfffeffff; bit 16
  371.         xchg    eax, ebx
  372.         call    IOAPIC_write
  373.         ret
  374. endp
  375.  
  376. proc disable_irq stdcall, irq_line:dword
  377.         mov     ebx, [irq_line]
  378.         cmp     [irq_mode], IRQ_APIC
  379.         je      .APIC
  380.  
  381.         mov     edx, 0x21
  382.         cmp     ebx, 8
  383.         jb      @F
  384.  
  385.         mov     edx, 0xA1
  386.         sub     ebx, 8
  387. @@:
  388.         in      al, dx
  389.         bts     eax, ebx
  390.         out     dx, al
  391.         ret
  392. .APIC:
  393.         shl     ebx, 1
  394.         add     ebx, 0x10
  395.         mov     eax, ebx
  396.         call    IOAPIC_read
  397.         or      eax, 0x10000; bit 16
  398.         xchg    eax, ebx
  399.         call    IOAPIC_write
  400.         ret
  401. endp
  402.  
  403. align 4
  404. pci_irq_fixup:
  405.  
  406.         push    ebp
  407.  
  408.         mov     esi, [acpi_dev_data]
  409.         mov     ebx, [acpi_dev_size]
  410.  
  411.         lea     edi, [esi+ebx]
  412.  
  413. .iterate:
  414.  
  415.         cmp     esi, edi
  416.         jae     .done
  417.  
  418.         mov     eax, [esi]
  419.  
  420.         cmp     eax, -1
  421.         je      .done
  422.  
  423.         movzx   ebx, al
  424.         movzx   ebp, ah
  425.  
  426.         stdcall pci_read32, ebp, ebx, 0
  427.  
  428.         cmp     eax, [esi+4]
  429.         jne     .skip
  430.  
  431.         mov     eax, [esi+8]
  432.         stdcall pci_write8, ebp, ebx, 0x3C, eax
  433. .skip:
  434.         add     esi, 16
  435.         jmp     .iterate
  436.  
  437. .done:
  438. .fail:
  439.         pop     ebp
  440.         ret
  441.  
  442. align 4
  443. get_clock_ns:
  444.         push    ebx
  445.         pushfd
  446.         cli
  447.  
  448.         mov     ebx, [hpet_base]
  449. @@:
  450.         mov     edx, [ebx+0xF4]
  451.         mov     eax, [ebx+0xF0]
  452.         mov     ecx, [ebx+0xF4]
  453.         cmp     ecx, edx
  454.         jnz     @B
  455.  
  456.         mov     ecx, [hpet_period]
  457.         mov     ebx, edx
  458.         imul    ebx, ecx
  459.         mul     ecx
  460.         add     edx, ebx
  461.  
  462.         popfd
  463.         pop     ebx
  464.         ret
  465.  
  466.