Subversion Repositories Kolibri OS

Rev

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