Subversion Repositories Kolibri OS

Rev

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