Subversion Repositories Kolibri OS

Rev

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

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