Subversion Repositories Kolibri OS

Rev

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