Advertisement
Guest User

Untitled

a guest
Nov 17th, 2023
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Nim 2.83 KB | None | 0 0
  1.  
  2. type
  3.   InterruptDescriptor64  {.packed.} = object
  4.     offset1: uint16   # offset bits 0..15
  5.     selector: uint16  # code segment selector in GDT or LDT
  6.     ist: uint8        # bits 0..2 holds Interrupt Stack Table offset, rest of bits zero
  7.     typeAttributes: uint8  # gate type, dpl, and p fields
  8.     offset2: uint16   # offset bits 16..31
  9.     offset3: uint32   # offset bits 32..63
  10.     zero: uint32      # reserved
  11.  
  12. # AMD64 Architecture Programmer's Manual Volume 2, page 291.
  13. type
  14.   InterruptHandlerStack {.packed, exportc.} = object
  15.     instructionPointer: uint64
  16.     codeSegment: uint64
  17.     cpuFlags: uint64
  18.     stackPointer: uint64
  19.     stackSegment: uint64
  20.  
  21. type
  22.   IDTR  {.packed.} = object
  23.     limit: uint16
  24.     base: uint64
  25.  
  26.  
  27. const IDTSize = 256
  28. const erroringVectors = [8, 10, 11, 12, 13, 14, 17, 21, 29, 30]
  29. var idt {.exportc.} : array[IDTSize, InterruptDescriptor64]
  30. var idtr {.exportc.} : IDTR
  31.  
  32.  
  33. proc genericHandler*(stack: var InterruptHandlerStack) {.exportc, cdecl.} =
  34.   echo "Generic happened. Halting.", stack
  35.   asm """
  36.    cli
  37.    hlt
  38.  """
  39.  
  40. proc errorHandler*(stack: var InterruptHandlerStack, error: uint64) {.exportc, cdecl.} =
  41.   echo "Error happened. Halting.", stack
  42.   echo "Error: ", error
  43.   asm """
  44.    cli
  45.    hlt
  46.  """
  47.  
  48.  
  49. proc interruptWrapper*() {.exportc, asmNoStackFrame.} =
  50.   asm """
  51.    push %rax
  52.    push %rcx
  53.    push %rdx
  54.    push %r8
  55.    push %r9
  56.    push %r10
  57.    push %r11
  58.  
  59.    enter $8, $0
  60.    mov %rsp, %rax
  61.    add $96, %rax
  62.    push %rax
  63.    call genericHandler
  64.    leave
  65.  
  66.    pop %r11
  67.    pop %r10
  68.    pop %r9
  69.    pop %r8
  70.    pop %rdx
  71.    pop %rcx
  72.    pop %rax
  73.  
  74.    iretq
  75.  """
  76. proc errorInterruptWrapper*() {.exportc, asmNoStackFrame.} =
  77.   asm """
  78.    push %rax
  79.    push %rcx
  80.    push %rdx
  81.    push %r8
  82.    push %r9
  83.    push %r10
  84.    push %r11
  85.  
  86.    enter $16, $0
  87.    mov %rsp, %rax
  88.    add $80, %rax
  89.    push [%rax]
  90.    add $32, %rax
  91.    push %rax
  92.    call errorHandler
  93.    leave
  94.  
  95.    pop %r11
  96.    pop %r10
  97.    pop %r9
  98.    pop %r8
  99.    pop %rdx
  100.    pop %rcx
  101.    pop %rax
  102.  
  103.    iretq
  104.  """
  105.  
  106.  
  107. proc setupIDT*() {.noconv, exportc.} =
  108.   var
  109.     addrGeneric: uint64 = cast[uint64](interruptWrapper)
  110.     addrError: uint64 = cast[uint64](errorInterruptWrapper)
  111.     address: uint64
  112.   idtr.limit = IDTSize * sizeof(InterruptDescriptor64) - 1
  113.   idtr.base = cast[uint64](idt.addr)
  114.  
  115.   for i in 0..<32:
  116.     if i in erroringVectors:
  117.       address = addrError
  118.     else:
  119.       address = addrGeneric
  120.  
  121.     idt[i].offset1 = address.uint16
  122.     idt[i].offset2 = (address shr 16).uint16
  123.     idt[i].offset3 = (address shr 32).uint32
  124.     idt[i].selector = 0x08
  125.     idt[i].ist = 0
  126.     idt[i].typeAttributes = 0x8E
  127.     idt[i].zero = 0
  128.  
  129. proc loadIDT*() =
  130.   asm """
  131.    lidt `idtr`
  132.  """
  133.  
  134. proc enableInterrupts*() =
  135.   asm """
  136.    sti
  137.  """
  138.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement