apbootstrap.s 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Start an Application Processor. This must be placed on a 4KB boundary
  3. * somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
  4. * due to some shortcuts below it's restricted further to within the 1st
  5. * 64KB. The AP starts in real-mode, with
  6. * CS selector set to the startup memory address/16;
  7. * CS base set to startup memory address;
  8. * CS limit set to 64KB;
  9. * CPL and IP set to 0.
  10. */
  11. #include "mem.h"
  12. #define NOP BYTE $0x90 /* NOP */
  13. #define LGDT(gdtptr) BYTE $0x0F; /* LGDT */ \
  14. BYTE $0x01; BYTE $0x16; \
  15. WORD $gdtptr
  16. #define FARJUMP16(s, o) BYTE $0xEA; /* far jump to ptr16:16 */ \
  17. WORD $o; WORD $s; \
  18. NOP; NOP; NOP
  19. #define FARJUMP32(s, o) BYTE $0x66; /* far jump to ptr32:16 */ \
  20. BYTE $0xEA; LONG $o; WORD $s
  21. #define DELAY BYTE $0xEB; /* JMP .+2 */ \
  22. BYTE $0x00
  23. #define INVD BYTE $0x0F; BYTE $0x08
  24. #define WBINVD BYTE $0x0F; BYTE $0x09
  25. /*
  26. * Macros for calculating offsets within the page directory base
  27. * and page tables. Note that these are assembler-specific hence
  28. * the '<<2'.
  29. */
  30. #define PDO(a) (((((a))>>22) & 0x03FF)<<2)
  31. #define PTO(a) (((((a))>>12) & 0x03FF)<<2)
  32. TEXT apbootstrap(SB), $0
  33. FARJUMP16(0, _apbootstrap(SB))
  34. TEXT _apvector(SB), $0 /* address APBOOTSTRAP+0x08 */
  35. LONG $0
  36. TEXT _appdb(SB), $0 /* address APBOOTSTRAP+0x0C */
  37. LONG $0
  38. TEXT _apapic(SB), $0 /* address APBOOTSTRAP+0x10 */
  39. LONG $0
  40. TEXT _apbootstrap(SB), $0 /* address APBOOTSTRAP+0x14 */
  41. MOVW CS, AX
  42. MOVW AX, DS /* initialise DS */
  43. LGDT(gdtptr(SB)) /* load a basic gdt */
  44. MOVL CR0, AX
  45. ORL $1, AX
  46. MOVL AX, CR0 /* turn on protected mode */
  47. DELAY /* JMP .+2 */
  48. BYTE $0xB8; WORD $SELECTOR(1, SELGDT, 0)/* MOVW $SELECTOR(1, SELGDT, 0), AX */
  49. MOVW AX, DS
  50. MOVW AX, ES
  51. MOVW AX, FS
  52. MOVW AX, GS
  53. MOVW AX, SS
  54. FARJUMP32(SELECTOR(2, SELGDT, 0), _ap32-KZERO(SB))
  55. /*
  56. * For Pentiums and higher, the code that enables paging must come from
  57. * pages that are identity mapped.
  58. * To this end double map KZERO at virtual 0 and undo the mapping once virtual
  59. * nirvana has been obtained.
  60. */
  61. TEXT _ap32(SB), $0
  62. MOVL _appdb-KZERO(SB), CX /* physical address of PDB */
  63. MOVL (PDO(KZERO))(CX), DX /* double-map KZERO at 0 */
  64. MOVL DX, (PDO(0))(CX)
  65. MOVL CX, CR3 /* load and flush the mmu */
  66. MOVL CR0, DX
  67. ORL $0x80010000, DX /* PG|WP */
  68. ANDL $~0x6000000A, DX /* ~(CD|NW|TS|MP) */
  69. MOVL $_appg(SB), AX
  70. MOVL DX, CR0 /* turn on paging */
  71. JMP* AX
  72. TEXT _appg(SB), $0
  73. MOVL CX, AX /* physical address of PDB */
  74. ORL $KZERO, AX
  75. MOVL $0, (PDO(0))(AX) /* undo double-map of KZERO at 0 */
  76. MOVL CX, CR3 /* load and flush the mmu */
  77. MOVL $(MACHADDR+MACHSIZE-4), SP
  78. MOVL $0, AX
  79. PUSHL AX
  80. POPFL
  81. MOVL _apapic(SB), AX
  82. MOVL AX, (SP)
  83. MOVL _apvector(SB), AX
  84. CALL* AX
  85. _aphalt:
  86. HLT
  87. JMP _aphalt
  88. TEXT gdt(SB), $0
  89. LONG $0x0000; LONG $0
  90. LONG $0xFFFF; LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
  91. LONG $0xFFFF; LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
  92. TEXT gdtptr(SB), $0
  93. WORD $(3*8-1)
  94. LONG $gdt-KZERO(SB)