l.s 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  1. #include "x16.h"
  2. #include "mem.h"
  3. #ifdef PXE
  4. #define PDB 0x90000 /* temporary page tables (24KB) */
  5. #else
  6. #define PDB 0x08000
  7. #endif PXE
  8. #define NoScreenBlank 1
  9. /*#define ResetDiscs 1*/
  10. TEXT origin(SB), $0
  11. /*
  12. * This part of l.s is used only in the boot kernel.
  13. * It assumes that we are in real address mode, i.e.,
  14. * that we look like an 8086.
  15. *
  16. * Make sure the segments are reasonable.
  17. * If we were started directly from the BIOS
  18. * (i.e. no MS-DOS) then DS may not be
  19. * right.
  20. */
  21. MOVW CS, AX
  22. MOVW AX, DS
  23. #ifdef NoScreenBlank
  24. /*
  25. * Get the current video mode. If it isn't mode 3,
  26. * set text mode 3.
  27. * Well, no. Windows95 won't co-operate here so we have
  28. * to explicitly set mode 3.
  29. */
  30. XORL AX, AX
  31. MOVB $0x0F, AH
  32. INT $0x10 /* get current video mode in AL */
  33. CMPB AL, $03
  34. JEQ sayhello
  35. #endif /* NoScreenBlank */
  36. XORL AX, AX
  37. MOVB $0x03, AL
  38. INT $0x10 /* set video mode in AL */
  39. sayhello:
  40. LWI(hello(SB), rSI)
  41. CALL16(biosputs(SB))
  42. #ifdef ResetDiscs
  43. XORL AX, AX /* reset disc system */
  44. XORL DX, DX
  45. MOVB $0x80, DL
  46. INT $0x13
  47. #endif /* ResetDiscs */
  48. #ifdef DOTCOM
  49. /*
  50. * relocate everything to a half meg and jump there
  51. * - looks weird because it is being assembled by a 32 bit
  52. * assembler for a 16 bit world
  53. *
  54. * only b.com does this - not 9load
  55. */
  56. MOVL $0,BX
  57. INCL BX
  58. SHLL $15,BX
  59. MOVL BX,CX
  60. MOVW BX,ES
  61. MOVL $0,SI
  62. MOVL SI,DI
  63. CLD
  64. REP
  65. MOVSL
  66. /*
  67. * Jump to the copied image;
  68. * fix up the DS for the new location.
  69. */
  70. FARJUMP16(0x8000, _start8000(SB))
  71. TEXT _start8000(SB), $0
  72. MFSR(rCS, rAX) /* fix up DS, ES (0x8000) */
  73. MTSR(rAX, rDS)
  74. MTSR(rAX, rES)
  75. /*
  76. * If we are already in protected mode, have to get back
  77. * to real mode before trying any privileged operations
  78. * (like going into protected mode...).
  79. * Try to reset with a restart vector.
  80. */
  81. MFCR(rCR0, rAX) /* are we in protected mode? */
  82. ANDI(0x0001, rAX)
  83. JEQ _real
  84. CLR(rBX)
  85. MTSR(rBX, rES)
  86. LWI(0x0467, rBX) /* reset entry point */
  87. LWI(_start8000(SB), rAX) /* offset within segment */
  88. BYTE $0x26
  89. BYTE $0x89
  90. BYTE $0x07 /* MOVW AX, ES:[BX] */
  91. LBI(0x69, rBL)
  92. MFSR(rCS, rAX) /* segment */
  93. BYTE $0x26
  94. BYTE $0x89
  95. BYTE $0x07 /* MOVW AX, ES:[BX] */
  96. CLR(rDX)
  97. OUTPORTB(0x70, 0x8F)
  98. OUTPORTB(0x71, 0x0A)
  99. FARJUMP16(0xFFFF, 0x0000) /* reset */
  100. #endif /* DOTCOM */
  101. _real:
  102. /*
  103. * do things that need to be done in real mode.
  104. * the results get written to CONFADDR (0x1200)
  105. * in a series of <4-byte-magic-number><block-of-data>
  106. * the data length is dependent on the magic number.
  107. *
  108. * this gets parsed by conf.c:/^readlsconf
  109. *
  110. * N.B. CALL16 kills rDI, so we can't call anything.
  111. */
  112. LWI(0x0000, rAX)
  113. MTSR(rAX, rES)
  114. LWI(0x1200, rDI)
  115. /*
  116. * turn off interrupts
  117. */
  118. CLI
  119. /*
  120. * detect APM1.2 bios support
  121. */
  122. /* save DI */
  123. SW(rDI, rock(SB))
  124. /* disconnect anyone else */
  125. LWI(0x5304, rAX)
  126. LWI(0x0000, rBX)
  127. INT $0x15
  128. /* connect */
  129. CLC
  130. LWI(0x5303, rAX)
  131. LWI(0x0000, rBX)
  132. INT $0x15
  133. CLI /* apm put interrupts back? */
  134. JC noapm
  135. OPSIZE; PUSHR(rSI)
  136. OPSIZE; PUSHR(rBX)
  137. PUSHR(rDI)
  138. PUSHR(rDX)
  139. PUSHR(rCX)
  140. PUSHR(rAX)
  141. /* put DI, ES back */
  142. LW(rock(SB), rDI)
  143. LWI(0x0000, rAX)
  144. MTSR(rAX, rES)
  145. /*
  146. * write APM data. first four bytes are APM\0.
  147. */
  148. LWI(0x5041, rAX)
  149. STOSW
  150. LWI(0x004d, rAX)
  151. STOSW
  152. LWI(8, rCX)
  153. apmmove:
  154. POPR(rAX)
  155. STOSW
  156. LOOP apmmove
  157. noapm:
  158. /*
  159. * end of real mode hacks: write terminator, put ES back.
  160. */
  161. LWI(0x0000, rAX)
  162. STOSW
  163. STOSW
  164. MFSR(rCS, rAX) /* fix up ES (0x8000) */
  165. MTSR(rAX, rES)
  166. /*
  167. * goto protected mode
  168. */
  169. /* MOVL tgdtptr(SB),GDTR /**/
  170. BYTE $0x0f
  171. BYTE $0x01
  172. BYTE $0x16
  173. WORD $tgdtptr(SB)
  174. LWI(1, rAX)
  175. /* MOV AX,MSW */
  176. BYTE $0x0F; BYTE $0x01; BYTE $0xF0
  177. /*
  178. * clear prefetch queue (weird code to avoid optimizations)
  179. */
  180. /* JMP .+2 */
  181. BYTE $0xEB
  182. BYTE $0x00
  183. /*
  184. * set all segs
  185. */
  186. /* MOVW $SELECTOR(1, SELGDT, 0),AX /**/
  187. BYTE $0xc7
  188. BYTE $0xc0
  189. WORD $SELECTOR(1, SELGDT, 0)
  190. MOVW AX,DS
  191. MOVW AX,SS
  192. MOVW AX,ES
  193. MOVW AX,FS
  194. MOVW AX,GS
  195. /* JMPFAR SELECTOR(2, SELGDT, 0):$mode32bit(SB) /**/
  196. BYTE $0x66
  197. BYTE $0xEA
  198. LONG $mode32bit-KZERO(SB)
  199. WORD $SELECTOR(2, SELGDT, 0)
  200. TEXT mode32bit(SB),$0
  201. /*
  202. * make a bottom level page table page that maps the first
  203. * 16 meg of physical memory
  204. */
  205. MOVL $PDB, DI /* clear 6 pages for the tables etc. */
  206. XORL AX, AX
  207. MOVL $(6*BY2PG), CX
  208. SHRL $2, CX
  209. CLD
  210. REP; STOSL
  211. MOVL $PDB, AX /* phys addr of temporary page table */
  212. MOVL $(4*1024),CX /* pte's per page */
  213. MOVL $((((4*1024)-1)<<PGSHIFT)|PTEVALID|PTEKERNEL|PTEWRITE),BX
  214. setpte:
  215. MOVL BX,-4(AX)(CX*4)
  216. SUBL $(1<<PGSHIFT),BX
  217. LOOP setpte
  218. /*
  219. * make a top level page table page that maps the first
  220. * 16 meg of memory to 0 thru 16meg and to KZERO thru KZERO+16meg
  221. */
  222. MOVL AX,BX
  223. ADDL $(4*BY2PG),AX
  224. ADDL $(PTEVALID|PTEKERNEL|PTEWRITE),BX
  225. MOVL BX,0(AX)
  226. MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+0)(AX)
  227. ADDL $BY2PG,BX
  228. MOVL BX,4(AX)
  229. MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+4)(AX)
  230. ADDL $BY2PG,BX
  231. MOVL BX,8(AX)
  232. MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+8)(AX)
  233. ADDL $BY2PG,BX
  234. MOVL BX,12(AX)
  235. MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+12)(AX)
  236. /*
  237. * point processor to top level page & turn on paging
  238. *
  239. * this produces the apparently harmless "VMX|F(125):468 Dis 0x0:0x0"
  240. * message in the VMware log.
  241. */
  242. MOVL AX,CR3
  243. MOVL CR0,AX
  244. ORL $0X80000000,AX
  245. MOVL AX,CR0
  246. /*
  247. * use a jump to an absolute location to get the PC into
  248. * KZERO.
  249. */
  250. LEAL tokzero(SB),AX
  251. JMP* AX
  252. /*
  253. * When we load 9load from DOS, the bootstrap jumps
  254. * to the instruction right after `JUMP', which gets
  255. * us into kzero.
  256. *
  257. * The name prevents it from being optimized away.
  258. */
  259. TEXT jumplabel(SB), $0
  260. BYTE $'J'; BYTE $'U'; BYTE $'M'; BYTE $'P'
  261. LEAL tokzero(SB),AX
  262. JMP* AX
  263. TEXT tokzero(SB),$0
  264. /*
  265. * Clear BSS
  266. */
  267. LEAL edata(SB),SI
  268. MOVL SI,DI
  269. ADDL $4,DI
  270. MOVL $0,AX
  271. MOVL AX,(SI)
  272. LEAL end(SB),CX
  273. SUBL DI,CX
  274. SHRL $2,CX
  275. CLD
  276. REP
  277. MOVSL
  278. /*
  279. * stack and mach
  280. */
  281. MOVL $mach0(SB),SP
  282. MOVL SP,m(SB)
  283. MOVL $0,0(SP)
  284. ADDL $(MACHSIZE-4),SP /* start stack above machine struct */
  285. CALL main(SB)
  286. loop:
  287. JMP loop
  288. GLOBL mach0+0(SB), $MACHSIZE
  289. GLOBL m(SB), $4
  290. /*
  291. * gdt to get us to 32-bit/segmented/unpaged mode
  292. */
  293. TEXT tgdt(SB),$0
  294. /* null descriptor */
  295. LONG $0
  296. LONG $0
  297. /* data segment descriptor for 4 gigabytes (PL 0) */
  298. LONG $(0xFFFF)
  299. LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
  300. /* exec segment descriptor for 4 gigabytes (PL 0) */
  301. LONG $(0xFFFF)
  302. LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
  303. /*
  304. * pointer to initial gdt
  305. */
  306. TEXT tgdtptr(SB),$0
  307. WORD $(3*8)
  308. LONG $tgdt-KZERO(SB)
  309. /*
  310. * Output a string to the display.
  311. * String argument is in rSI.
  312. */
  313. TEXT biosputs(SB), $0
  314. PUSHA
  315. CLR(rBX)
  316. _BIOSputs:
  317. LODSB
  318. ORB(rAL, rAL)
  319. JEQ _BIOSputsret
  320. LBI(0x0E, rAH)
  321. BIOSCALL(0x10)
  322. JMP _BIOSputs
  323. _BIOSputsret:
  324. POPA
  325. RET
  326. /*
  327. * input a byte
  328. */
  329. TEXT inb(SB),$0
  330. MOVL p+0(FP),DX
  331. XORL AX,AX
  332. INB
  333. RET
  334. /*
  335. * input a short from a port
  336. */
  337. TEXT ins(SB), $0
  338. MOVL p+0(FP), DX
  339. XORL AX, AX
  340. OPSIZE; INL
  341. RET
  342. /*
  343. * input a long from a port
  344. */
  345. TEXT inl(SB), $0
  346. MOVL p+0(FP), DX
  347. XORL AX, AX
  348. INL
  349. RET
  350. /*
  351. * output a byte
  352. */
  353. TEXT outb(SB),$0
  354. MOVL p+0(FP),DX
  355. MOVL b+4(FP),AX
  356. OUTB
  357. RET
  358. /*
  359. * output a short to a port
  360. */
  361. TEXT outs(SB), $0
  362. MOVL p+0(FP), DX
  363. MOVL s+4(FP), AX
  364. OPSIZE; OUTL
  365. RET
  366. /*
  367. * output a long to a port
  368. */
  369. TEXT outl(SB), $0
  370. MOVL p+0(FP), DX
  371. MOVL s+4(FP), AX
  372. OUTL
  373. RET
  374. /*
  375. * input a string of bytes from a port
  376. */
  377. TEXT insb(SB),$0
  378. MOVL p+0(FP),DX
  379. MOVL a+4(FP),DI
  380. MOVL c+8(FP),CX
  381. CLD; REP; INSB
  382. RET
  383. /*
  384. * input a string of shorts from a port
  385. */
  386. TEXT inss(SB),$0
  387. MOVL p+0(FP),DX
  388. MOVL a+4(FP),DI
  389. MOVL c+8(FP),CX
  390. CLD
  391. REP; OPSIZE; INSL
  392. RET
  393. /*
  394. * output a string of bytes to a port
  395. */
  396. TEXT outsb(SB),$0
  397. MOVL p+0(FP),DX
  398. MOVL a+4(FP),SI
  399. MOVL c+8(FP),CX
  400. CLD; REP; OUTSB
  401. RET
  402. /*
  403. * output a string of shorts to a port
  404. */
  405. TEXT outss(SB),$0
  406. MOVL p+0(FP),DX
  407. MOVL a+4(FP),SI
  408. MOVL c+8(FP),CX
  409. CLD
  410. REP; OPSIZE; OUTSL
  411. RET
  412. /*
  413. * input a string of longs from a port
  414. */
  415. TEXT insl(SB),$0
  416. MOVL p+0(FP),DX
  417. MOVL a+4(FP),DI
  418. MOVL c+8(FP),CX
  419. CLD; REP; INSL
  420. RET
  421. /*
  422. * output a string of longs to a port
  423. */
  424. TEXT outsl(SB),$0
  425. MOVL p+0(FP),DX
  426. MOVL a+4(FP),SI
  427. MOVL c+8(FP),CX
  428. CLD; REP; OUTSL
  429. RET
  430. /*
  431. * routines to load/read various system registers
  432. */
  433. GLOBL idtptr(SB),$6
  434. TEXT putidt(SB),$0 /* interrupt descriptor table */
  435. MOVL t+0(FP),AX
  436. MOVL AX,idtptr+2(SB)
  437. MOVL l+4(FP),AX
  438. MOVW AX,idtptr(SB)
  439. MOVL idtptr(SB),IDTR
  440. RET
  441. TEXT putcr3(SB),$0 /* top level page table pointer */
  442. MOVL t+0(FP),AX
  443. MOVL AX,CR3
  444. RET
  445. TEXT getcr0(SB),$0 /* coprocessor bits */
  446. MOVL CR0,AX
  447. RET
  448. TEXT getcr2(SB),$0 /* fault address */
  449. MOVL CR2,AX
  450. RET
  451. TEXT getcr3(SB),$0 /* page directory base */
  452. MOVL CR3,AX
  453. RET
  454. TEXT getcr4(SB), $0 /* CR4 - extensions */
  455. MOVL CR4, AX
  456. RET
  457. /*
  458. * special traps
  459. */
  460. TEXT intr0(SB),$0
  461. PUSHL $0
  462. PUSHL $0
  463. JMP intrcommon
  464. TEXT intr1(SB),$0
  465. PUSHL $0
  466. PUSHL $1
  467. JMP intrcommon
  468. TEXT intr2(SB),$0
  469. PUSHL $0
  470. PUSHL $2
  471. JMP intrcommon
  472. TEXT intr3(SB),$0
  473. PUSHL $0
  474. PUSHL $3
  475. JMP intrcommon
  476. TEXT intr4(SB),$0
  477. PUSHL $0
  478. PUSHL $4
  479. JMP intrcommon
  480. TEXT intr5(SB),$0
  481. PUSHL $0
  482. PUSHL $5
  483. JMP intrcommon
  484. TEXT intr6(SB),$0
  485. PUSHL $0
  486. PUSHL $6
  487. JMP intrcommon
  488. TEXT intr7(SB),$0
  489. PUSHL $0
  490. PUSHL $7
  491. JMP intrcommon
  492. TEXT intr8(SB),$0
  493. PUSHL $8
  494. JMP intrcommon
  495. TEXT intr9(SB),$0
  496. PUSHL $0
  497. PUSHL $9
  498. JMP intrcommon
  499. TEXT intr10(SB),$0
  500. PUSHL $10
  501. JMP intrcommon
  502. TEXT intr11(SB),$0
  503. PUSHL $11
  504. JMP intrcommon
  505. TEXT intr12(SB),$0
  506. PUSHL $12
  507. JMP intrcommon
  508. TEXT intr13(SB),$0
  509. PUSHL $13
  510. JMP intrcommon
  511. TEXT intr14(SB),$0
  512. PUSHL $14
  513. JMP intrcommon
  514. TEXT intr15(SB),$0
  515. PUSHL $0
  516. PUSHL $15
  517. JMP intrcommon
  518. TEXT intr16(SB),$0
  519. PUSHL $0
  520. PUSHL $16
  521. JMP intrcommon
  522. TEXT intr24(SB),$0
  523. PUSHL $0
  524. PUSHL $24
  525. JMP intrcommon
  526. TEXT intr25(SB),$0
  527. PUSHL $0
  528. PUSHL $25
  529. JMP intrcommon
  530. TEXT intr26(SB),$0
  531. PUSHL $0
  532. PUSHL $26
  533. JMP intrcommon
  534. TEXT intr27(SB),$0
  535. PUSHL $0
  536. PUSHL $27
  537. JMP intrcommon
  538. TEXT intr28(SB),$0
  539. PUSHL $0
  540. PUSHL $28
  541. JMP intrcommon
  542. TEXT intr29(SB),$0
  543. PUSHL $0
  544. PUSHL $29
  545. JMP intrcommon
  546. TEXT intr30(SB),$0
  547. PUSHL $0
  548. PUSHL $30
  549. JMP intrcommon
  550. TEXT intr31(SB),$0
  551. PUSHL $0
  552. PUSHL $31
  553. JMP intrcommon
  554. TEXT intr32(SB),$0
  555. PUSHL $0
  556. PUSHL $32
  557. JMP intrcommon
  558. TEXT intr33(SB),$0
  559. PUSHL $0
  560. PUSHL $33
  561. JMP intrcommon
  562. TEXT intr34(SB),$0
  563. PUSHL $0
  564. PUSHL $34
  565. JMP intrcommon
  566. TEXT intr35(SB),$0
  567. PUSHL $0
  568. PUSHL $35
  569. JMP intrcommon
  570. TEXT intr36(SB),$0
  571. PUSHL $0
  572. PUSHL $36
  573. JMP intrcommon
  574. TEXT intr37(SB),$0
  575. PUSHL $0
  576. PUSHL $37
  577. JMP intrcommon
  578. TEXT intr38(SB),$0
  579. PUSHL $0
  580. PUSHL $38
  581. JMP intrcommon
  582. TEXT intr39(SB),$0
  583. PUSHL $0
  584. PUSHL $39
  585. JMP intrcommon
  586. TEXT intr64(SB),$0
  587. PUSHL $0
  588. PUSHL $64
  589. JMP intrcommon
  590. TEXT intrbad(SB),$0
  591. PUSHL $0
  592. PUSHL $0x1ff
  593. JMP intrcommon
  594. intrcommon:
  595. PUSHL DS
  596. PUSHL ES
  597. PUSHL FS
  598. PUSHL GS
  599. PUSHAL
  600. MOVL $(KDSEL),AX
  601. MOVW AX,DS
  602. MOVW AX,ES
  603. LEAL 0(SP),AX
  604. PUSHL AX
  605. CALL trap(SB)
  606. POPL AX
  607. POPAL
  608. POPL GS
  609. POPL FS
  610. POPL ES
  611. POPL DS
  612. ADDL $8,SP /* error code and trap type */
  613. IRETL
  614. /*
  615. * interrupt level is interrupts on or off
  616. */
  617. TEXT spllo(SB),$0
  618. PUSHFL
  619. POPL AX
  620. STI
  621. RET
  622. TEXT splhi(SB),$0
  623. PUSHFL
  624. POPL AX
  625. CLI
  626. RET
  627. TEXT splx(SB),$0
  628. MOVL s+0(FP),AX
  629. PUSHL AX
  630. POPFL
  631. RET
  632. /*
  633. * do nothing whatsoever till interrupt happens
  634. */
  635. TEXT idle(SB),$0
  636. HLT
  637. RET
  638. /*
  639. * Try to determine the CPU type which requires fiddling with EFLAGS.
  640. * If the Id bit can be toggled then the CPUID instruciton can be used
  641. * to determine CPU identity and features. First have to check if it's
  642. * a 386 (Ac bit can't be set). If it's not a 386 and the Id bit can't be
  643. * toggled then it's an older 486 of some kind.
  644. *
  645. * cpuid(id[], &ax, &dx);
  646. */
  647. #define CPUID BYTE $0x0F; BYTE $0xA2 /* CPUID, argument in AX */
  648. TEXT cpuid(SB), $0
  649. MOVL $0x240000, AX
  650. PUSHL AX
  651. POPFL /* set Id|Ac */
  652. PUSHFL
  653. POPL BX /* retrieve value */
  654. MOVL $0, AX
  655. PUSHL AX
  656. POPFL /* clear Id|Ac, EFLAGS initialised */
  657. PUSHFL
  658. POPL AX /* retrieve value */
  659. XORL BX, AX
  660. TESTL $0x040000, AX /* Ac */
  661. JZ _cpu386 /* can't set this bit on 386 */
  662. TESTL $0x200000, AX /* Id */
  663. JZ _cpu486 /* can't toggle this bit on some 486 */
  664. MOVL $0, AX
  665. CPUID
  666. MOVL id+0(FP), BP
  667. MOVL BX, 0(BP) /* "Genu" "Auth" "Cyri" */
  668. MOVL DX, 4(BP) /* "ineI" "enti" "xIns" */
  669. MOVL CX, 8(BP) /* "ntel" "cAMD" "tead" */
  670. MOVL $1, AX
  671. CPUID
  672. JMP _cpuid
  673. _cpu486:
  674. MOVL $0x400, AX
  675. MOVL $0, DX
  676. JMP _cpuid
  677. _cpu386:
  678. MOVL $0x300, AX
  679. MOVL $0, DX
  680. _cpuid:
  681. MOVL ax+4(FP), BP
  682. MOVL AX, 0(BP)
  683. MOVL dx+8(FP), BP
  684. MOVL DX, 0(BP)
  685. RET
  686. /*
  687. * basic timing loop to determine CPU frequency
  688. */
  689. TEXT aamloop(SB),$0
  690. MOVL c+0(FP),CX
  691. aaml1:
  692. AAM
  693. LOOP aaml1
  694. RET
  695. TEXT hello(SB), $0
  696. BYTE $'P'; BYTE $'l'; BYTE $'a'; BYTE $'n';
  697. BYTE $' '; BYTE $'9'; BYTE $' '; BYTE $'f';
  698. BYTE $'r'; BYTE $'o'; BYTE $'m'; BYTE $' ';
  699. BYTE $'B'; BYTE $'e'; BYTE $'l'; BYTE $'l';
  700. BYTE $' '; BYTE $'L'; BYTE $'a'; BYTE $'b';
  701. BYTE $'s';
  702. BYTE $'\r';
  703. BYTE $'\n';
  704. BYTE $'\z';
  705. TEXT rock(SB), $0
  706. BYTE $0; BYTE $0; BYTE $0; BYTE $0;
  707. GLOBL pxe(SB), $4
  708. #ifdef PXE
  709. DATA pxe+0(SB)/4, $1
  710. #else
  711. DATA pxe+0(SB)/4, $0
  712. #endif /* PXE */