l32v.s 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. #include "x16.h"
  2. #include "mem.h"
  3. #define WRMSR BYTE $0x0F; BYTE $0x30 /* WRMSR, argument in AX/DX (lo/hi) */
  4. #define RDTSC BYTE $0x0F; BYTE $0x31 /* RDTSC, result in AX/DX (lo/hi) */
  5. #define RDMSR BYTE $0x0F; BYTE $0x32 /* RDMSR, result in AX/DX (lo/hi) */
  6. TEXT _start32v(SB),$0
  7. CLI
  8. MOVL $edata(SB), DI
  9. XORL AX, AX
  10. MOVL $end(SB), CX
  11. SUBL DI, CX /* end-edata bytes */
  12. SHRL $2, CX /* end-edata doublewords */
  13. CLD
  14. REP; STOSL /* clear BSS */
  15. MOVL CR3, AX
  16. ADDL $KZERO, AX /* VA of PDB */
  17. MOVL AX, mach0pdb(SB)
  18. ADDL $(3*BY2PG), AX
  19. MOVL AX, mach0m(SB)
  20. MOVL AX, m(SB) /* initialise global Mach pointer */
  21. MOVL $0, 0(AX) /* initialise machp()->machno */
  22. ADDL $MACHSIZE, AX
  23. MOVL AX, SP /* initialise stack */
  24. MOVL AX, mach0gdt(SB)
  25. ADDL $BY2PG, AX
  26. MOVL AX, memstart(SB)
  27. MOVL $0x240000, AX /* try to set Id|Ac in EFLAGS */
  28. PUSHL AX
  29. POPFL
  30. PUSHFL /* retrieve EFLAGS -> BX */
  31. POPL BX
  32. MOVL $0, AX /* clear Id|Ac, EFLAGS initialised */
  33. PUSHL AX
  34. POPFL
  35. PUSHFL /* retrieve EFLAGS -> AX */
  36. XORL BX, (SP) /* togglable bits */
  37. CALL main(SB)
  38. /*
  39. * Park a processor. Should never fall through a return from main to here,
  40. * should only be called by application processors when shutting down.
  41. */
  42. TEXT idle(SB), $0
  43. _idle:
  44. STI
  45. HLT
  46. JMP _idle
  47. TEXT hlt(SB), $0
  48. STI
  49. HLT
  50. RET
  51. /*
  52. */
  53. TEXT _warp9o(SB), $0
  54. MOVL entry+0(FP), CX
  55. MOVL $multibootheader-KZERO(SB), BX /* multiboot data pointer */
  56. MOVL $0x2badb002, AX /* multiboot magic */
  57. CLI
  58. JMP* CX
  59. JMP _idle
  60. /*
  61. * Macro for calculating offset within the page directory base.
  62. * Note that this is assembler-specific hence the '<<2'.
  63. */
  64. #define PDO(a) (((((a))>>22) & 0x03FF)<<2)
  65. /*
  66. */
  67. TEXT _warp9(SB), $0
  68. CLI
  69. MOVL entry+0(FP), BP
  70. MOVL CR3, CX /* load address of PDB */
  71. ADDL $KZERO, CX
  72. MOVL PDO(KZERO)(CX), DX /* double-map KZERO at 0 */
  73. MOVL DX, PDO(0)(CX)
  74. MOVL CR3, CX
  75. MOVL CX, CR3 /* load and flush the mmu */
  76. MOVL $_start32id<>-KZERO(SB), AX
  77. JMP* AX /* jump to identity-map */
  78. TEXT _start32id<>(SB), $0
  79. MOVL CR0, DX /* turn off paging */
  80. ANDL $~0x80000000, DX /* ~(PG) */
  81. MOVL $_stop32pg<>-KZERO(SB), AX
  82. MOVL DX, CR0
  83. JMP* AX /* forward into the past */
  84. TEXT _stop32pg<>(SB), $0
  85. MOVL $multibootheader-KZERO(SB), BX /* multiboot data pointer */
  86. MOVL $0x2badb002, AX /* multiboot magic */
  87. JMP* BP
  88. JMP _idle
  89. /*
  90. * input a byte
  91. */
  92. TEXT inb(SB),$0
  93. MOVL p+0(FP),DX
  94. XORL AX,AX
  95. INB
  96. RET
  97. /*
  98. * input a short from a port
  99. */
  100. TEXT ins(SB), $0
  101. MOVL p+0(FP), DX
  102. XORL AX, AX
  103. OPSIZE; INL
  104. RET
  105. /*
  106. * input a long from a port
  107. */
  108. TEXT inl(SB), $0
  109. MOVL p+0(FP), DX
  110. XORL AX, AX
  111. INL
  112. RET
  113. /*
  114. * output a byte
  115. */
  116. TEXT outb(SB),$0
  117. MOVL p+0(FP),DX
  118. MOVL b+4(FP),AX
  119. OUTB
  120. RET
  121. /*
  122. * output a short to a port
  123. */
  124. TEXT outs(SB), $0
  125. MOVL p+0(FP), DX
  126. MOVL s+4(FP), AX
  127. OPSIZE; OUTL
  128. RET
  129. /*
  130. * output a long to a port
  131. */
  132. TEXT outl(SB), $0
  133. MOVL p+0(FP), DX
  134. MOVL s+4(FP), AX
  135. OUTL
  136. RET
  137. /*
  138. * input a string of bytes from a port
  139. */
  140. TEXT insb(SB),$0
  141. MOVL p+0(FP),DX
  142. MOVL a+4(FP),DI
  143. MOVL c+8(FP),CX
  144. CLD; REP; INSB
  145. RET
  146. /*
  147. * input a string of shorts from a port
  148. */
  149. TEXT inss(SB),$0
  150. MOVL p+0(FP),DX
  151. MOVL a+4(FP),DI
  152. MOVL c+8(FP),CX
  153. CLD
  154. REP; OPSIZE; INSL
  155. RET
  156. /*
  157. * output a string of bytes to a port
  158. */
  159. TEXT outsb(SB),$0
  160. MOVL p+0(FP),DX
  161. MOVL a+4(FP),SI
  162. MOVL c+8(FP),CX
  163. CLD; REP; OUTSB
  164. RET
  165. /*
  166. * output a string of shorts to a port
  167. */
  168. TEXT outss(SB),$0
  169. MOVL p+0(FP),DX
  170. MOVL a+4(FP),SI
  171. MOVL c+8(FP),CX
  172. CLD
  173. REP; OPSIZE; OUTSL
  174. RET
  175. /*
  176. * input a string of longs from a port
  177. */
  178. TEXT insl(SB),$0
  179. MOVL p+0(FP),DX
  180. MOVL a+4(FP),DI
  181. MOVL c+8(FP),CX
  182. CLD; REP; INSL
  183. RET
  184. /*
  185. * output a string of longs to a port
  186. */
  187. TEXT outsl(SB),$0
  188. MOVL p+0(FP),DX
  189. MOVL a+4(FP),SI
  190. MOVL c+8(FP),CX
  191. CLD; REP; OUTSL
  192. RET
  193. /*
  194. * routines to load/read various system registers
  195. */
  196. TEXT lgdt(SB), $0 /* GDTR - global descriptor table */
  197. MOVL gdtptr+0(FP), AX
  198. MOVL (AX), GDTR
  199. RET
  200. TEXT lidt(SB), $0 /* IDTR - interrupt descriptor table */
  201. MOVL idtptr+0(FP), AX
  202. MOVL (AX), IDTR
  203. RET
  204. TEXT putcr3(SB),$0 /* top level page table pointer */
  205. MOVL t+0(FP),AX
  206. MOVL AX,CR3
  207. RET
  208. TEXT getcr0(SB),$0 /* coprocessor bits */
  209. MOVL CR0,AX
  210. RET
  211. TEXT getcr2(SB),$0 /* fault address */
  212. MOVL CR2,AX
  213. RET
  214. TEXT getcr3(SB),$0 /* page directory base */
  215. MOVL CR3,AX
  216. RET
  217. TEXT getcr4(SB), $0 /* CR4 - extensions */
  218. MOVL CR4, AX
  219. RET
  220. TEXT _cycles(SB), $0 /* time stamp counter */
  221. RDTSC
  222. MOVL vlong+0(FP), CX /* &vlong */
  223. MOVL AX, 0(CX) /* lo */
  224. MOVL DX, 4(CX) /* hi */
  225. RET
  226. TEXT rdmsr(SB), $0 /* model-specific register */
  227. MOVL index+0(FP), CX
  228. RDMSR
  229. MOVL vlong+4(FP), CX /* &vlong */
  230. MOVL AX, 0(CX) /* lo */
  231. MOVL DX, 4(CX) /* hi */
  232. RET
  233. TEXT wrmsr(SB), $0
  234. MOVL index+0(FP), CX
  235. MOVL lo+4(FP), AX
  236. MOVL hi+8(FP), DX
  237. WRMSR
  238. RET
  239. TEXT mb386(SB), $0
  240. POPL AX /* return PC */
  241. PUSHFL
  242. PUSHL CS
  243. PUSHL AX
  244. IRETL
  245. /*
  246. * special traps
  247. */
  248. TEXT intr0(SB),$0
  249. PUSHL $0
  250. PUSHL $0
  251. JMP intrcommon
  252. TEXT intr1(SB),$0
  253. PUSHL $0
  254. PUSHL $1
  255. JMP intrcommon
  256. TEXT intr2(SB),$0
  257. PUSHL $0
  258. PUSHL $2
  259. JMP intrcommon
  260. TEXT intr3(SB),$0
  261. PUSHL $0
  262. PUSHL $3
  263. JMP intrcommon
  264. TEXT intr4(SB),$0
  265. PUSHL $0
  266. PUSHL $4
  267. JMP intrcommon
  268. TEXT intr5(SB),$0
  269. PUSHL $0
  270. PUSHL $5
  271. JMP intrcommon
  272. TEXT intr6(SB),$0
  273. PUSHL $0
  274. PUSHL $6
  275. JMP intrcommon
  276. TEXT intr7(SB),$0
  277. PUSHL $0
  278. PUSHL $7
  279. JMP intrcommon
  280. TEXT intr8(SB),$0
  281. PUSHL $8
  282. JMP intrcommon
  283. TEXT intr9(SB),$0
  284. PUSHL $0
  285. PUSHL $9
  286. JMP intrcommon
  287. TEXT intr10(SB),$0
  288. PUSHL $10
  289. JMP intrcommon
  290. TEXT intr11(SB),$0
  291. PUSHL $11
  292. JMP intrcommon
  293. TEXT intr12(SB),$0
  294. PUSHL $12
  295. JMP intrcommon
  296. TEXT intr13(SB),$0
  297. PUSHL $13
  298. JMP intrcommon
  299. TEXT intr14(SB),$0
  300. PUSHL $14
  301. JMP intrcommon
  302. TEXT intr15(SB),$0
  303. PUSHL $0
  304. PUSHL $15
  305. JMP intrcommon
  306. TEXT intr16(SB),$0
  307. PUSHL $0
  308. PUSHL $16
  309. JMP intrcommon
  310. TEXT intr24(SB),$0
  311. PUSHL $0
  312. PUSHL $24
  313. JMP intrcommon
  314. TEXT intr25(SB),$0
  315. PUSHL $0
  316. PUSHL $25
  317. JMP intrcommon
  318. TEXT intr26(SB),$0
  319. PUSHL $0
  320. PUSHL $26
  321. JMP intrcommon
  322. TEXT intr27(SB),$0
  323. PUSHL $0
  324. PUSHL $27
  325. JMP intrcommon
  326. TEXT intr28(SB),$0
  327. PUSHL $0
  328. PUSHL $28
  329. JMP intrcommon
  330. TEXT intr29(SB),$0
  331. PUSHL $0
  332. PUSHL $29
  333. JMP intrcommon
  334. TEXT intr30(SB),$0
  335. PUSHL $0
  336. PUSHL $30
  337. JMP intrcommon
  338. TEXT intr31(SB),$0
  339. PUSHL $0
  340. PUSHL $31
  341. JMP intrcommon
  342. TEXT intr32(SB),$0
  343. PUSHL $0
  344. PUSHL $32
  345. JMP intrcommon
  346. TEXT intr33(SB),$0
  347. PUSHL $0
  348. PUSHL $33
  349. JMP intrcommon
  350. TEXT intr34(SB),$0
  351. PUSHL $0
  352. PUSHL $34
  353. JMP intrcommon
  354. TEXT intr35(SB),$0
  355. PUSHL $0
  356. PUSHL $35
  357. JMP intrcommon
  358. TEXT intr36(SB),$0
  359. PUSHL $0
  360. PUSHL $36
  361. JMP intrcommon
  362. TEXT intr37(SB),$0
  363. PUSHL $0
  364. PUSHL $37
  365. JMP intrcommon
  366. TEXT intr38(SB),$0
  367. PUSHL $0
  368. PUSHL $38
  369. JMP intrcommon
  370. TEXT intr39(SB),$0
  371. PUSHL $0
  372. PUSHL $39
  373. JMP intrcommon
  374. TEXT intr64(SB),$0
  375. PUSHL $0
  376. PUSHL $64
  377. JMP intrcommon
  378. TEXT intrbad(SB),$0
  379. PUSHL $0
  380. PUSHL $0x1ff
  381. JMP intrcommon
  382. intrcommon:
  383. PUSHL DS
  384. PUSHL ES
  385. PUSHL FS
  386. PUSHL GS
  387. PUSHAL
  388. MOVL $(KDSEL),AX
  389. MOVW AX,DS
  390. MOVW AX,ES
  391. LEAL 0(SP),AX
  392. PUSHL AX
  393. CALL trap(SB)
  394. POPL AX
  395. POPAL
  396. POPL GS
  397. POPL FS
  398. POPL ES
  399. POPL DS
  400. ADDL $8,SP /* error code and trap type */
  401. IRETL
  402. /*
  403. * interrupt level is interrupts on or off
  404. */
  405. TEXT spllo(SB),$0
  406. PUSHFL
  407. POPL AX
  408. STI
  409. RET
  410. TEXT splhi(SB),$0
  411. PUSHFL
  412. POPL AX
  413. CLI
  414. RET
  415. TEXT splx(SB),$0
  416. MOVL s+0(FP),AX
  417. PUSHL AX
  418. POPFL
  419. RET
  420. /*
  421. * Try to determine the CPU type which requires fiddling with EFLAGS.
  422. * If the Id bit can be toggled then the CPUID instruciton can be used
  423. * to determine CPU identity and features. First have to check if it's
  424. * a 386 (Ac bit can't be set). If it's not a 386 and the Id bit can't be
  425. * toggled then it's an older 486 of some kind.
  426. *
  427. * cpuid(id[], &ax, &dx);
  428. */
  429. #define CPUID BYTE $0x0F; BYTE $0xA2 /* CPUID, argument in AX */
  430. TEXT cpuid(SB), $0
  431. MOVL $0x240000, AX
  432. PUSHL AX
  433. POPFL /* set Id|Ac */
  434. PUSHFL
  435. POPL BX /* retrieve value */
  436. MOVL $0, AX
  437. PUSHL AX
  438. POPFL /* clear Id|Ac, EFLAGS initialised */
  439. PUSHFL
  440. POPL AX /* retrieve value */
  441. XORL BX, AX
  442. TESTL $0x040000, AX /* Ac */
  443. JZ _cpu386 /* can't set this bit on 386 */
  444. TESTL $0x200000, AX /* Id */
  445. JZ _cpu486 /* can't toggle this bit on some 486 */
  446. MOVL $0, AX
  447. CPUID
  448. MOVL id+0(FP), BP
  449. MOVL BX, 0(BP) /* "Genu" "Auth" "Cyri" */
  450. MOVL DX, 4(BP) /* "ineI" "enti" "xIns" */
  451. MOVL CX, 8(BP) /* "ntel" "cAMD" "tead" */
  452. MOVL $1, AX
  453. CPUID
  454. JMP _cpuid
  455. _cpu486:
  456. MOVL $0x400, AX
  457. MOVL $0, DX
  458. JMP _cpuid
  459. _cpu386:
  460. MOVL $0x300, AX
  461. MOVL $0, DX
  462. _cpuid:
  463. MOVL ax+4(FP), BP
  464. MOVL AX, 0(BP)
  465. MOVL dx+8(FP), BP
  466. MOVL DX, 0(BP)
  467. RET
  468. /*
  469. * basic timing loop to determine CPU frequency
  470. */
  471. TEXT aamloop(SB),$0
  472. MOVL c+0(FP),CX
  473. aaml1:
  474. AAM
  475. LOOP aaml1
  476. RET
  477. GLOBL pxe(SB), $4
  478. #ifdef PXE
  479. DATA pxe+0(SB)/4, $1
  480. #else
  481. DATA pxe+0(SB)/4, $0
  482. #endif /* PXE */