Subversion Repositories Kolibri OS

Rev

Rev 6942 | 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: 7136 $
  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         = 0x20
  22. APIC_TPR        = 0x80
  23. APIC_EOI        = 0xb0
  24. APIC_LDR        = 0xd0
  25. APIC_DFR        = 0xe0
  26. APIC_SVR        = 0xf0
  27. APIC_ISR        = 0x100
  28. APIC_ESR        = 0x280
  29. APIC_ICRL       = 0x300
  30. APIC_ICRH       = 0x310
  31. APIC_LVT_LINT0  = 0x350
  32. APIC_LVT_LINT1  = 0x360
  33. APIC_LVT_err    = 0x370
  34.  
  35. ; APIC timer
  36. APIC_LVT_timer  = 0x320
  37. APIC_timer_div  = 0x3e0
  38. APIC_timer_init = 0x380
  39. APIC_timer_cur  = 0x390
  40. ; IOAPIC
  41. IOAPIC_ID       = 0x0
  42. IOAPIC_VER      = 0x1
  43. IOAPIC_ARB      = 0x2
  44. IOAPIC_REDTBL   = 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.  
  445.         mov     eax, [hpet_base]
  446.         test    eax, eax
  447.         jz      .old_tics
  448.  
  449.         push    ebx
  450.         push    esi
  451.         pushfd
  452.         cli
  453.  
  454.         mov     ebx, eax
  455. @@:
  456.         mov     edx, [ebx+0xF4]
  457.         mov     eax, [ebx+0xF0]
  458.         mov     ecx, [ebx+0xF4]
  459.         cmp     ecx, edx
  460.         jne     @B
  461.         popfd
  462.  
  463. ;96-bit arithmetic
  464. ;ebx - low dword
  465. ;esi - medium dword
  466. ;edx - high dword
  467.  
  468.         mul     [hpet_period]
  469.         mov     ebx, eax
  470.         mov     esi, edx
  471.  
  472.         mov     eax, ecx
  473.         mul     [hpet_period]
  474.         add     esi, eax
  475.         adc     edx, 0
  476.         mov     eax, ebx
  477.         mov     ebx, esi
  478.         shrd    eax, ebx, 10
  479.         shrd    esi, edx, 10
  480.         mov     edx, esi
  481.  
  482.         pop     esi
  483.         pop     ebx
  484.         ret
  485.  
  486. .old_tics:
  487.         mov     eax, [timer_ticks]
  488.         mov     edx, 10000000
  489.         mul     edx
  490.         ret
  491.  
  492. align 4
  493. acpi_get_root_ptr:
  494.         mov     eax, [acpi_rsdp]
  495.         ret
  496.