smp.S 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. # SMP
  3. Expected output: "SMP started"
  4. TODO get working + answer all of:
  5. - http://stackoverflow.com/questions/16364817/assessing-the-apic-and-creating-ipis-in-x86-assembly
  6. Closest quesiton so far! Almost there!
  7. Table 8-1. Broadcast INIT-SIPI-SIPI Sequence and Choice of Timeouts contains actual code!
  8. TODO: how to sleep the right ammount of time?
  9. - http://stackoverflow.com/questions/15091165/inter-processor-interrupt-usage
  10. - http://stackoverflow.com/questions/1516530/assembly-and-multicore-cpus?lq=1
  11. - http://stackoverflow.com/questions/1622388/running-code-on-different-processor-x86-assembly
  12. - http://stackoverflow.com/questions/26452323/how-can-we-use-multi-core-and-cpu-on-assembly-boot-loader-x86
  13. - http://stackoverflow.com/questions/2986931/the-way-cores-processes-and-threads-work-exactly?rq=1
  14. - http://stackoverflow.com/questions/419486/multithreading-and-interrupts
  15. - http://stackoverflow.com/questions/663958/how-to-control-which-core-a-process-runs-on
  16. - http://stackoverflow.com/questions/714905/threads-in-x86-assembler-using-the-gnu-assember-as
  17. - http://stackoverflow.com/questions/7308391/how-is-concurrency-done-in-intel-x86-assembly
  18. - http://stackoverflow.com/questions/980999/what-does-multicore-assembly-language-look-like
  19. - http://stackoverflow.com/questions/28047092/by-which-instruction-the-secondary-core-is-triggered-while-starting-the-secondar?rq=1
  20. - http://stackoverflow.com/questions/23962839/how-to-correctly-use-a-startup-ipi-to-start-an-application-processor?rq=1
  21. - https://github.com/cirosantilli/oszur11-operating-system-examples/tree/1af6451852887fac3d7206d4d09714c181c81d1e/Chapter_07_Threads
  22. */
  23. /* Must be a multiple of 0x1000. */
  24. .equ STARTUP_CODE_ADDRESS, 0x1000
  25. .equ SPINLOCK_ADDRESS, 0x2000
  26. #include "common.h"
  27. BEGIN
  28. CLEAR
  29. /*
  30. TODO do we need 32-bit mode? I think yes because the APIC register
  31. FEE00300 is too high for 16-bit?
  32. */
  33. PROTECTED_MODE
  34. /*
  35. Setup the code that will be run
  36. on the other processors when they start up.
  37. Should be somewhere into the first 1Mb,
  38. as processors starte in real mode.
  39. */
  40. cld
  41. mov $init_len, %ecx
  42. mov $init, %esi
  43. mov $STARTUP_CODE_ADDRESS, %edi
  44. rep movsb
  45. /* Setup the value that threads will modify for us. */
  46. movb $0, SPINLOCK_ADDRESS
  47. /*
  48. Move data into the lower ICR register:
  49. this should start the other processors.
  50. - Destination Shorthand = 11 = all except self
  51. - Trigger Mode = ?
  52. - Level = ?
  53. - Delivery Status = 0 = Idle
  54. - Destination Mode = ? = Does not matter since shorthand used
  55. - Delivery Mode = 110 = Startup
  56. - Vector = ? = does it matter for SIPI?
  57. */
  58. /* Load address of ICR low dword into ESI. */
  59. mov PIC_ICR_ADDRESS, %esi
  60. /* Load ICR encoding for broadcast INIT IPI to all APs. */
  61. mov $0x000C4500, %eax
  62. /* Broadcast INIT IPI to all APs */
  63. mov %eax, (%esi)
  64. /*
  65. 10-millisecond delay loop.
  66. TODO I think I'm going to do this with the PIT.
  67. */
  68. /*
  69. Load ICR encoding for broadcast SIPI IP to all APs.
  70. The low byte of this is the vector which encodes the staring address for the processors!
  71. This address is multiplied by 0x1000: processors start at CS = vector * 0x100 and IP = 0.
  72. */
  73. mov $0x000C4600 + STARTUP_CODE_ADDRESS / 0x1000, %eax
  74. /* Broadcast SIPI IPI to all APs. */
  75. mov %eax, (%esi)
  76. /* 200-microsecond delay loop. */
  77. /* TODO */
  78. /* Broadcast second SIPI IPI to all APs */
  79. mov %eax, (%esi)
  80. /* TODO improve this spinlock. */
  81. not_started:
  82. cmpb $1, SPINLOCK_ADDRESS
  83. jne not_started
  84. VGA_PRINT_STRING $message
  85. /* Testing if it is possible in 16-bit real mode. */
  86. /*PRINT_STRING $message*/
  87. hlt
  88. message:
  89. .asciz "SMP started"
  90. .code16
  91. init:
  92. xor %ax, %ax
  93. mov %ax, %ds
  94. movb $1, SPINLOCK_ADDRESS
  95. /* TODO mandatory? */
  96. wbinvd
  97. hlt
  98. .equ init_len, . - init