Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2012. 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+PG_NOCACHE
  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.  
  125.         cmp     [LAPIC_BASE], 0
  126.         jne     .done
  127.  
  128.         stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW+PG_NOCACHE
  129.         mov     [LAPIC_BASE], eax
  130.         mov     esi, eax
  131.  
  132.         ; Program Destination Format Register for Flat mode.
  133.         mov     eax, [esi + APIC_DFR]
  134.         or      eax, 0xf0000000
  135.         mov     [esi + APIC_DFR], eax
  136.  
  137.         ; Program Logical Destination Register.
  138.         mov     eax, [esi + APIC_LDR]
  139.         ;and  eax, 0xff000000
  140.         and     eax, 0x00ffffff
  141.         or      eax, 0x01000000;!!!!!!!!!!!!
  142.         mov     [esi + APIC_LDR], eax
  143.  
  144.         ; Task Priority Register initialization.
  145.         mov     eax, [esi + APIC_TPR]
  146.         and     eax, 0xffffff00
  147.         mov     [esi + APIC_TPR], eax
  148.  
  149.         ; Flush the queue
  150.         mov     edx, 0
  151. .nxt2:
  152.         mov     ecx, 32
  153.         mov     eax, [esi + APIC_ISR + edx]
  154. .nxt:
  155.         shr     eax, 1
  156.         jnc     @f
  157.         mov     dword [esi + APIC_EOI], 0; EOI
  158. @@:
  159.         loop    .nxt
  160.  
  161.         add     edx, 0x10
  162.         cmp     edx, 0x170
  163.         jbe     .nxt2
  164.  
  165.         ; Spurious-Interrupt Vector Register initialization.
  166.         mov     eax, [esi + APIC_SVR]
  167.         or      eax, 0x1ff
  168.         and     eax, 0xfffffdff
  169.         mov     [esi + APIC_SVR], eax
  170.  
  171.         ; Initialize LVT LINT0 register. (INTR)
  172.         mov     eax, 0x00700
  173.         ; mov eax, 0x10700
  174.         mov     [esi + APIC_LVT_LINT0], eax
  175.  
  176.         ; Initialize LVT LINT1 register. (NMI)
  177.         mov     eax, 0x00400
  178.         mov     [esi + APIC_LVT_LINT1], eax
  179.  
  180.         ; Initialize LVT Error register.
  181.         mov     eax, [esi + APIC_LVT_err]
  182.         or      eax, 0x10000; bit 16
  183.         mov     [esi + APIC_LVT_err], eax
  184.  
  185.         ; LAPIC timer
  186.         ; pre init
  187.         mov     dword[esi + APIC_timer_div], 1011b; 1
  188.         mov     dword[esi + APIC_timer_init], 0xffffffff; max val
  189.         push    esi
  190.         mov     esi, 640    ; wait 0.64 sec
  191.         call    delay_ms
  192.         pop     esi
  193.         mov     eax, [esi + APIC_timer_cur]; read current tick couner
  194.         xor     eax, 0xffffffff   ; eax = 0xffffffff - eax
  195.         shr     eax, 6      ; eax /= 64; APIC ticks per 0.01 sec
  196.  
  197.         ; Start (every 0.01 sec)
  198.         mov     dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
  199.         mov     dword[esi + APIC_timer_init], eax
  200.  
  201. .done:
  202.         ret
  203.  
  204. ;===========================================================
  205. ; IOAPIC implementation
  206. align 4
  207. IOAPIC_read:
  208. ; in : EAX - IOAPIC register
  209. ; out: EAX - readed value
  210.         push    esi
  211.         mov     esi, [IOAPIC_base]
  212.         mov     [esi], eax
  213.         mov     eax, [esi + 0x10]
  214.         pop     esi
  215.         ret
  216.  
  217. align 4
  218. IOAPIC_write:
  219. ; in :  EAX - IOAPIC register
  220. ;       EBX - value
  221. ; out:  none
  222.         push    esi
  223.         mov     esi, [IOAPIC_base]
  224.         mov     [esi], eax
  225.         mov     [esi + 0x10], ebx
  226.         pop     esi
  227.         ret
  228. ;===========================================================
  229. ; Remap all IRQ to 0x20+ Vectors
  230. ; IRQ0 to vector 0x20, IRQ1 to vector 0x21....
  231. align 4
  232. PIC_init:
  233.         cli
  234.         mov     al, 0x11        ;  icw4, edge triggered
  235.         out     0x20, al
  236.         out     0xA0, al
  237.  
  238.         mov     al, 0x20        ;  generate 0x20 +
  239.         out     0x21, al
  240.         mov     al, 0x28        ;  generate 0x28 +
  241.         out     0xA1, al
  242.  
  243.         mov     al, 0x04        ;  slave at irq2
  244.         out     0x21, al
  245.         mov     al, 0x02        ;  at irq9
  246.         out     0xA1, al
  247.  
  248.         mov     al, 0x01        ;  8086 mode
  249.         out     0x21, al
  250.         out     0xA1, al
  251.  
  252.         call    IRQ_mask_all
  253.         ; mov   dword[irq_type_to_set], IRQ_TYPE_PIC
  254.         ret
  255.  
  256. ; -----------------------------------------
  257. ; TIMER SET TO 1/100 S
  258. align 4
  259. PIT_init:
  260.         mov     al, 0x34   ; set to 100Hz
  261.         out     0x43, al
  262.         mov     al, 0x9b   ; lsb    1193180 / 1193
  263.         out     0x40, al
  264.         mov     al, 0x2e   ; msb
  265.         out     0x40, al
  266.         ret
  267.  
  268. ; -----------------------------------------
  269. align 4
  270. unmask_timer:
  271.         cmp     [irq_mode], IRQ_APIC
  272.         je      @f
  273.  
  274.         stdcall enable_irq, 0
  275.         ret
  276. @@:
  277.         ; use PIT
  278.         ; in some systems PIT no connected to IOAPIC
  279.         ; mov   eax, 0x14
  280.         ; call  IOAPIC_read
  281.         ; mov   ah, 0x09                ; Delivery Mode: Lowest Priority, Destination Mode: Logical
  282.         ; mov   al, 0x20
  283.         ; or    eax, 0x10000            ; Mask Interrupt
  284.         ; mov   ebx, eax
  285.         ; mov   eax, 0x14
  286.         ; call  IOAPIC_write
  287.         ; stdcall enable_irq, 2
  288.         ; ret
  289.  
  290.         ; use LAPIC timer
  291.         mov     esi, [LAPIC_BASE]
  292.         mov     eax, [esi + APIC_LVT_timer]
  293.         and     eax, 0xfffeffff
  294.         mov     [esi + APIC_LVT_timer], eax
  295.         ret
  296.  
  297. ; -----------------------------------------
  298. ; Disable all IRQ
  299. align 4
  300. IRQ_mask_all:
  301.         cmp     [irq_mode], IRQ_APIC
  302.         je      .APIC
  303.  
  304.         mov     al, 0xFF
  305.         out     0x21, al
  306.         out     0xA1, al
  307.         mov     ecx, 0x1000
  308.         ret
  309. .APIC:
  310.         mov     ecx, [IRQ_COUNT]
  311.         mov     eax, 0x10
  312. @@:
  313.         mov     ebx, eax
  314.         call    IOAPIC_read
  315.         or      eax, 0x10000; bit 16
  316.         xchg    eax, ebx
  317.         call    IOAPIC_write
  318.         inc     eax
  319.         inc     eax
  320.         loop    @b
  321.         ret
  322.  
  323. ; -----------------------------------------
  324. ; End Of Interrupt
  325. ; cl - IRQ number
  326. align 4
  327. irq_eoi:         ; __fastcall
  328.         cmp     [irq_mode], IRQ_APIC
  329.         je      .APIC
  330.  
  331.         cmp     cl, 8
  332.         mov     al, 0x20
  333.         jb      @f
  334.         out     0xa0, al
  335. @@:
  336.         out     0x20, al
  337.         ret
  338.  
  339. .APIC:
  340.         mov     eax, [LAPIC_BASE]
  341.         mov     dword [eax + APIC_EOI], 0; EOI
  342.         ret
  343.  
  344. ; -----------------------------------------
  345. ; from dll.inc
  346. align 4
  347. proc enable_irq stdcall, irq_line:dword
  348.         mov     ebx, [irq_line]
  349.         cmp     [irq_mode], IRQ_APIC
  350.         je      .APIC
  351.  
  352.         mov     edx, 0x21
  353.         cmp     ebx, 8
  354.         jb      @F
  355.  
  356.         mov     edx, 0xA1
  357.         sub     ebx, 8
  358. @@:
  359.         in      al, dx
  360.         btr     eax, ebx
  361.         out     dx, al
  362.         ret
  363. .APIC:
  364.         shl     ebx, 1
  365.         add     ebx, 0x10
  366.         mov     eax, ebx
  367.         call    IOAPIC_read
  368.         and     eax, 0xfffeffff; bit 16
  369.         xchg    eax, ebx
  370.         call    IOAPIC_write
  371.         ret
  372. endp
  373.  
  374. align 4
  375. pci_irq_fixup:
  376.  
  377.         push    ebp
  378.  
  379.         mov     esi, [acpi_dev_data]
  380.         mov     ebx, [acpi_dev_size]
  381.  
  382.         lea     edi, [esi+ebx]
  383.  
  384. .iterate:
  385.  
  386.         cmp     esi, edi
  387.         jae     .done
  388.  
  389.         mov     eax, [esi]
  390.  
  391.         cmp     eax, -1
  392.         je      .done
  393.  
  394.         movzx   ebx, al
  395.         movzx   ebp, ah
  396.  
  397.         stdcall pci_read32, ebp, ebx, 0
  398.  
  399.         cmp     eax, [esi+4]
  400.         jne     .skip
  401.  
  402.         mov     eax, [esi+8]
  403.         stdcall pci_write8, ebp, ebx, 0x3C, eax
  404. .skip:
  405.         add     esi, 16
  406.         jmp     .iterate
  407.  
  408. .done:
  409. .fail:
  410.         pop     ebp
  411.         ret
  412.  
  413.  
  414.  
  415.  
  416.  
  417.