Subversion Repositories Kolibri OS

Rev

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