224 lines
4.4 KiB
ArmAsm
224 lines
4.4 KiB
ArmAsm
.altmacro
|
|
|
|
.global __x86_64_apic_vectors
|
|
|
|
.set IRQ_REG_RAX, 0 * 8
|
|
.set IRQ_REG_RCX, 1 * 8
|
|
.set IRQ_REG_RDX, 2 * 8
|
|
.set IRQ_REG_RBX, 3 * 8
|
|
.set IRQ_REG_RSI, 4 * 8
|
|
.set IRQ_REG_RDI, 5 * 8
|
|
.set IRQ_REG_RBP, 6 * 8
|
|
.set IRQ_REG_R8, 7 * 8
|
|
.set IRQ_REG_R9, 8 * 8
|
|
.set IRQ_REG_R10, 9 * 8
|
|
.set IRQ_REG_R11, 10 * 8
|
|
.set IRQ_REG_R12, 11 * 8
|
|
.set IRQ_REG_R13, 12 * 8
|
|
.set IRQ_REG_R14, 13 * 8
|
|
.set IRQ_REG_R15, 14 * 8
|
|
|
|
// 15 registers + stack align word if needed
|
|
.set IRQ_STATE_SIZE, 15 * 8
|
|
|
|
.macro IRQ_SWAPGS_IF_NEEDED, cs_off
|
|
cmpq $0x08, \cs_off(%rsp)
|
|
je 1f
|
|
swapgs
|
|
1:
|
|
.endm
|
|
|
|
.macro IRQ_SAVE_STATE
|
|
// Save state
|
|
subq $IRQ_STATE_SIZE, %rsp
|
|
|
|
movq %rax, IRQ_REG_RAX(%rsp)
|
|
movq %rcx, IRQ_REG_RCX(%rsp)
|
|
movq %rdx, IRQ_REG_RDX(%rsp)
|
|
movq %rbx, IRQ_REG_RBX(%rsp)
|
|
movq %rsi, IRQ_REG_RSI(%rsp)
|
|
movq %rdi, IRQ_REG_RDI(%rsp)
|
|
movq %rbp, IRQ_REG_RBP(%rsp)
|
|
movq %r8, IRQ_REG_R8(%rsp)
|
|
movq %r9, IRQ_REG_R9(%rsp)
|
|
movq %r10, IRQ_REG_R10(%rsp)
|
|
movq %r11, IRQ_REG_R11(%rsp)
|
|
movq %r12, IRQ_REG_R12(%rsp)
|
|
movq %r13, IRQ_REG_R13(%rsp)
|
|
movq %r14, IRQ_REG_R14(%rsp)
|
|
movq %r15, IRQ_REG_R15(%rsp)
|
|
|
|
// Save current stack into %rbp
|
|
movq %rsp, %rbp
|
|
|
|
// Force correct stack alignment
|
|
orq $0xF, %rsp
|
|
xorq $0xF, %rsp
|
|
.endm
|
|
|
|
.macro IRQ_RESTORE_STATE
|
|
// Restore the stack pointer
|
|
movq %rbp, %rsp
|
|
|
|
// Restore state
|
|
movq IRQ_REG_RAX(%rsp), %rax
|
|
movq IRQ_REG_RCX(%rsp), %rcx
|
|
movq IRQ_REG_RDX(%rsp), %rdx
|
|
movq IRQ_REG_RBX(%rsp), %rbx
|
|
movq IRQ_REG_RSI(%rsp), %rsi
|
|
movq IRQ_REG_RDI(%rsp), %rdi
|
|
movq IRQ_REG_RBP(%rsp), %rbp
|
|
movq IRQ_REG_R8(%rsp), %r8
|
|
movq IRQ_REG_R9(%rsp), %r9
|
|
movq IRQ_REG_R10(%rsp), %r10
|
|
movq IRQ_REG_R11(%rsp), %r11
|
|
movq IRQ_REG_R12(%rsp), %r12
|
|
movq IRQ_REG_R13(%rsp), %r13
|
|
movq IRQ_REG_R14(%rsp), %r14
|
|
movq IRQ_REG_R15(%rsp), %r15
|
|
|
|
addq $IRQ_STATE_SIZE, %rsp
|
|
.endm
|
|
|
|
.macro IRQ_VECTOR, n
|
|
irq_vector_\n:
|
|
// %rsp + 0: %rip
|
|
// %rsp + 8: %cs
|
|
IRQ_SWAPGS_IF_NEEDED 8
|
|
IRQ_SAVE_STATE
|
|
|
|
// Force correct segment registers
|
|
mov $0x10, %ax
|
|
mov %ax, %ss
|
|
mov %ax, %ds
|
|
mov %ax, %es
|
|
|
|
mov $\n, %rdi
|
|
mov %rbp, %rsi
|
|
call {irq_handler}
|
|
|
|
IRQ_RESTORE_STATE
|
|
IRQ_SWAPGS_IF_NEEDED 8
|
|
|
|
iretq
|
|
.endm
|
|
|
|
.macro IRQ_VECTOR_ENTRY, n
|
|
.quad irq_vector_\n
|
|
.endm
|
|
|
|
.macro IRQ_VECTORS, start, end
|
|
.set i, 0
|
|
.rept \end - \start
|
|
IRQ_VECTOR %i
|
|
.set i, i+1
|
|
.endr
|
|
.endm
|
|
|
|
.macro IRQ_VECTOR_ENTRIES, start, end
|
|
.set i, 0
|
|
.rept \end - \start
|
|
IRQ_VECTOR_ENTRY %i
|
|
.set i, i+1
|
|
.endr
|
|
.endm
|
|
|
|
.macro MSI_VECTOR, n
|
|
msi_vector_\n:
|
|
// %rsp + 0: %rip
|
|
// %rsp + 8: %cs
|
|
IRQ_SWAPGS_IF_NEEDED 8
|
|
IRQ_SAVE_STATE
|
|
|
|
// Force correct segment registers
|
|
mov $0x10, %ax
|
|
mov %ax, %ss
|
|
mov %ax, %ds
|
|
mov %ax, %es
|
|
|
|
mov $\n, %rdi
|
|
mov %rbp, %rsi
|
|
call {msi_handler}
|
|
|
|
IRQ_RESTORE_STATE
|
|
IRQ_SWAPGS_IF_NEEDED 8
|
|
|
|
iretq
|
|
.endm
|
|
|
|
.macro MSI_VECTOR_ENTRY, n
|
|
.quad msi_vector_\n
|
|
.endm
|
|
|
|
.macro MSI_VECTORS, start, end
|
|
.set i, 0
|
|
.rept \end - \start
|
|
MSI_VECTOR %i
|
|
.set i, i+1
|
|
.endr
|
|
.endm
|
|
|
|
.macro MSI_VECTOR_ENTRIES, start, end
|
|
.set i, 0
|
|
.rept \end - \start
|
|
MSI_VECTOR_ENTRY %i
|
|
.set i, i+1
|
|
.endr
|
|
.endm
|
|
|
|
.macro FILL_EMPTY_SPACE, start, end
|
|
.set i, 0
|
|
.rept \end - \start
|
|
.quad dummy_vector
|
|
.endr
|
|
.endm
|
|
|
|
.section .text
|
|
local_timer_vector:
|
|
IRQ_SWAPGS_IF_NEEDED 8
|
|
IRQ_SAVE_STATE
|
|
|
|
mov %rbp, %rdi
|
|
call {local_timer_irq_handler}
|
|
|
|
IRQ_RESTORE_STATE
|
|
IRQ_SWAPGS_IF_NEEDED 8
|
|
iretq
|
|
|
|
ipi_vector:
|
|
IRQ_SWAPGS_IF_NEEDED 8
|
|
IRQ_SAVE_STATE
|
|
|
|
call {ipi_handler}
|
|
jmp .
|
|
|
|
dummy_vector:
|
|
IRQ_SWAPGS_IF_NEEDED 8
|
|
IRQ_SAVE_STATE
|
|
|
|
call {dummy_irq_handler}
|
|
jmp .
|
|
|
|
IRQ_VECTORS {irq_vector_offset}, {irq_vector_offset} + {irq_vector_count}
|
|
MSI_VECTORS {msi_vector_offset}, {msi_vector_offset} + {msi_vector_count}
|
|
|
|
.section .rodata
|
|
// 224 vectors: 256 - 32 (exceptions)
|
|
.p2align 4
|
|
.type __x86_64_apic_vectors, @object
|
|
__x86_64_apic_vectors:
|
|
// Local timer IRQ: 0
|
|
.quad local_timer_vector
|
|
// Dummy entries (currently): 1..=2
|
|
.quad dummy_vector
|
|
.quad dummy_vector
|
|
// IPI vector: 3
|
|
.quad ipi_vector
|
|
// Regular IRQ vectors: 4..207
|
|
IRQ_VECTOR_ENTRIES {irq_vector_offset}, {irq_vector_offset} + {irq_vector_count}
|
|
// MSI vectors: 207..223
|
|
MSI_VECTOR_ENTRIES {msi_vector_offset}, {msi_vector_offset} + {msi_vector_count}
|
|
// Spurious interrupt vector: 223
|
|
.quad dummy_vector
|
|
.size __x86_64_apic_vectors, . - __x86_64_apic_vectors
|