|
|
1.1 root 1: #include "mem.h"
2:
3: #define OP16 BYTE $0x66
4: #define NOP XCHGL AX,AX
5:
6: /*
7: * about to walk all over ms/dos - turn off interrupts
8: */
9: TEXT origin(SB),$0
10:
11: CLI
12:
13: #ifdef BOOT
14: /*
15: * This part of l.s is used only in the boot kernel.
16: * It assumes that we are in real address mode, i.e.,
17: * that we look like an 8086.
18: */
19: /*
20: * relocate everything to a half meg and jump there
21: * - looks wierd because it is being assembled by a 32 bit
22: * assembler for a 16 bit world
23: */
24: MOVL $0,BX
25: INCL BX
26: SHLL $15,BX
27: MOVL BX,CX
28: MOVW BX,ES
29: MOVL $0,SI
30: MOVL SI,DI
31: CLD; REP; MOVSL
32: /* JMPFAR 0X8000:$lowcore(SB) /**/
33: BYTE $0xEA
34: WORD $lowcore(SB)
35: WORD $0X8000
36:
37: TEXT lowcore(SB),$0
38:
39: /*
40: * now that we're in low core, update the DS
41: */
42:
43: MOVW BX,DS
44:
45: /*
46: * goto protected mode
47: */
48: /* MOVL tgdtptr(SB),GDTR /**/
49: BYTE $0x0f
50: BYTE $0x01
51: BYTE $0x16
52: WORD $tgdtptr(SB)
53: MOVL CR0,AX
54: ORL $1,AX
55: MOVL AX,CR0
56:
57: /*
58: * clear prefetch queue (weird code to avoid optimizations)
59: */
60: CLC
61: JCC flush
62: MOVL AX,AX
63: flush:
64:
65: /*
66: * set all segs
67: */
68: /* MOVW $SELECTOR(1, SELGDT, 0),AX /**/
69: BYTE $0xc7
70: BYTE $0xc0
71: WORD $SELECTOR(1, SELGDT, 0)
72: MOVW AX,DS
73: MOVW AX,SS
74: MOVW AX,ES
75: MOVW AX,FS
76: MOVW AX,GS
77:
78: /* JMPFAR SELECTOR(2, SELGDT, 0):$mode32bit(SB) /**/
79: BYTE $0x66
80: BYTE $0xEA
81: LONG $mode32bit-KZERO(SB)
82: WORD $SELECTOR(2, SELGDT, 0)
83:
84: TEXT mode32bit(SB),$0
85:
86: #endif BOOT
87:
88: /*
89: * Clear BSS
90: */
91: LEAL edata-KZERO(SB),SI
92: MOVL SI,DI
93: ADDL $4,DI
94: MOVL $0,AX
95: MOVL AX,(SI)
96: LEAL end-KZERO(SB),CX
97: SUBL DI,CX
98: SHRL $2,CX
99: CLD; REP; MOVSL
100:
101: /*
102: * make a bottom level page table page that maps the first
103: * 16 meg of physical memory
104: */
105: LEAL tpt-KZERO(SB),AX /* get phys addr of temporary page table */
106: ADDL $(BY2PG-1),AX /* must be page alligned */
107: ANDL $(~(BY2PG-1)),AX /* ... */
108: MOVL $(1024),CX /* pte's per page */
109: MOVL $((((1024)-1)<<PGSHIFT)|PTEVALID|PTEKERNEL|PTEWRITE),BX
110: setpte:
111: MOVL BX,-4(AX)(CX*4)
112: SUBL $(1<<PGSHIFT),BX
113: LOOP setpte
114:
115: /*
116: * make a top level page table page that maps the first
117: * 16 meg of memory to 0 thru 16meg and to KZERO thru KZERO+16meg
118: */
119: MOVL AX,BX
120: ADDL $(BY2PG),AX
121: ADDL $(PTEVALID|PTEKERNEL|PTEWRITE),BX
122: MOVL BX,0(AX)
123: MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+0)(AX)
124:
125: /*
126: * point processor to top level page & turn on paging & make
127: * supervisor obey the R/W bit in the page map
128: */
129: MOVL AX,CR3
130: MOVL CR0,AX
131: ORL $0X80010000,AX
132: ANDL $~(0x40000000|0x20000000|0x8|0x2),AX /* CD=0, NW=0, TS=0, MP=0 */
133: MOVL AX,CR0
134:
135: /*
136: * use a jump to an absolute location to get the PC into
137: * KZERO.
138: */
139: LEAL tokzero(SB),AX
140: JMP* AX
141:
142: TEXT tokzero(SB),$0
143:
144: /*
145: * stack and mach
146: */
147: MOVL $mach0(SB),SP
148: MOVL SP,m(SB)
149: MOVL $0,0(SP)
150: ADDL $(MACHSIZE-4),SP /* start stack under machine struct */
151: MOVL $0, u(SB)
152:
153: /*
154: * clear flags
155: */
156: MOVL $0,AX
157: PUSHL AX
158: POPFL
159:
160: CALL main(SB)
161:
162: loop:
163: JMP loop
164:
165: GLOBL mach0+0(SB), $MACHSIZE
166: GLOBL u(SB), $4
167: GLOBL m(SB), $4
168: GLOBL tpt(SB), $(BY2PG*3)
169:
170: /*
171: * gdt to get us to 32-bit/segmented/unpaged mode
172: */
173: TEXT tgdt(SB),$0
174:
175: /* null descriptor */
176: LONG $0
177: LONG $0
178:
179: /* data segment descriptor for 4 gigabytes (PL 0) */
180: LONG $(0xFFFF)
181: LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
182:
183: /* exec segment descriptor for 4 gigabytes (PL 0) */
184: LONG $(0xFFFF)
185: LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
186:
187: /*
188: * pointer to initial gdt
189: */
190: TEXT tgdtptr(SB),$0
191:
192: WORD $(3*8)
193: LONG $tgdt-KZERO(SB)
194:
195: /*
196: * input a byte
197: */
198: TEXT inb(SB),$0
199:
200: MOVL p+0(FP),DX
201: XORL AX,AX
202: INB
203: RET
204:
205: /*
206: * input a string of bytes from a port
207: */
208: TEXT insb(SB),$0
209:
210: MOVL p+0(FP),DX
211: MOVL a+4(FP),DI
212: MOVL c+8(FP),CX
213: CLD; REP; INSB
214: RET
215:
216: /*
217: * output a byte
218: */
219: TEXT outb(SB),$0
220:
221: MOVL p+0(FP),DX
222: MOVL b+4(FP),AX
223: OUTB
224: RET
225:
226: /*
227: * output a string of bytes to a port
228: */
229: TEXT outsb(SB),$0
230:
231: MOVL p+0(FP),DX
232: MOVL a+4(FP),SI
233: MOVL c+8(FP),CX
234: CLD; REP; OUTSB
235: RET
236:
237: /*
238: * input a short from a port
239: */
240: TEXT ins(SB), $0
241:
242: MOVL p+0(FP), DX
243: XORL AX, AX
244: OP16; INL
245: RET
246:
247: /*
248: * input a string of shorts from a port
249: */
250: TEXT inss(SB),$0
251:
252: MOVL p+0(FP),DX
253: MOVL a+4(FP),DI
254: MOVL c+8(FP),CX
255: CLD; REP; OP16; INSL
256: RET
257:
258: /*
259: * input a long from a port
260: */
261: TEXT inl(SB), $0
262:
263: MOVL p+0(FP), DX
264: XORL AX, AX
265: INL
266: RET
267:
268: /*
269: * input a string of longs from a port
270: */
271: TEXT insl(SB),$0
272:
273: MOVL p+0(FP),DX
274: MOVL a+4(FP),DI
275: MOVL c+8(FP),CX
276: CLD; REP; INSL
277: RET
278:
279: /*
280: * output a short to a port
281: */
282: TEXT outs(SB), $0
283: MOVL p+0(FP), DX
284: MOVL s+4(FP), AX
285: OP16; OUTL
286: RET
287:
288: /*
289: * output a string of shorts to a port
290: */
291: TEXT outss(SB),$0
292:
293: MOVL p+0(FP),DX
294: MOVL a+4(FP),SI
295: MOVL c+8(FP),CX
296: CLD; REP; OP16; OUTSL
297: RET
298:
299: /*
300: * output a long to a port
301: */
302: TEXT outl(SB), $0
303: MOVL p+0(FP), DX
304: MOVL s+4(FP), AX
305: OUTL
306: RET
307:
308: /*
309: * output a string of longs to a port
310: */
311: TEXT outsl(SB),$0
312:
313: MOVL p+0(FP),DX
314: MOVL a+4(FP),SI
315: MOVL c+8(FP),CX
316: CLD; REP; OUTSL
317: RET
318:
319: /*
320: * test and set
321: */
322: TEXT tas(SB),$0
323: MOVL $0xdeadead,AX
324: MOVL l+0(FP),BX
325: XCHGL AX,(BX)
326: RET
327:
328: /*
329: * exchange 2 32-bit words, this is an interlocked (LOCK#) instruction
330: */
331: TEXT ilputl(SB),$0
332: MOVL v+4(FP),AX
333: MOVL a+0(FP),BX
334: XCHGL AX,(BX)
335: RET
336:
337: /*
338: * routines to load/read various system registers
339: */
340: GLOBL idtptr(SB),$6
341: TEXT putidt(SB),$0 /* interrupt descriptor table */
342: MOVL t+0(FP),AX
343: MOVL AX,idtptr+2(SB)
344: MOVL l+4(FP),AX
345: MOVW AX,idtptr(SB)
346: MOVL idtptr(SB),IDTR
347: RET
348:
349: GLOBL gdtptr(SB),$6
350: TEXT putgdt(SB),$0 /* global descriptor table */
351: MOVL t+0(FP),AX
352: MOVL AX,gdtptr+2(SB)
353: MOVL l+4(FP),AX
354: MOVW AX,gdtptr(SB)
355: MOVL gdtptr(SB),GDTR
356: RET
357:
358: TEXT putcr3(SB),$0 /* top level page table pointer */
359: MOVL t+0(FP),AX
360: MOVL AX,CR3
361: RET
362:
363: TEXT puttr(SB),$0 /* task register */
364: MOVL t+0(FP),AX
365: MOVW AX,TASK
366: RET
367:
368: TEXT getcr0(SB),$0 /* coprocessor bits */
369: MOVL CR0,AX
370: RET
371:
372: TEXT getcr2(SB),$0 /* fault address */
373: MOVL CR2,AX
374: RET
375:
376: #define FPOFF\
377: WAIT;\
378: MOVL CR0,AX;\
379: ORL $0x24,AX /* EM=1, NE=1 */;\
380: MOVL AX,CR0
381:
382: #define FPON\
383: MOVL CR0,AX;\
384: ANDL $~0x4,AX /* EM=0 */;\
385: MOVL AX,CR0
386:
387: TEXT fpoff(SB),$0 /* turn off floating point */
388: FPOFF
389: RET
390:
391: TEXT fpinit(SB),$0 /* turn on & init the floating point */
392: FPON
393: FINIT
394: WAIT
395: PUSHW $0x033E
396: FLDCW 0(SP) /* ignore underflow/precision, signal others */
397: POPW AX
398: WAIT
399: RET
400:
401: TEXT fpsave(SB),$0 /* save floating point state and turn off */
402: MOVL p+0(FP),AX
403: WAIT
404: FSAVE 0(AX)
405: FPOFF
406: RET
407:
408: TEXT fprestore(SB),$0 /* turn on floating point and restore regs */
409: FPON
410: MOVL p+0(FP),AX
411: FRSTOR 0(AX)
412: WAIT
413: RET
414:
415: TEXT fpstatus(SB),$0 /* get floating point status */
416: FSTSW AX
417: RET
418:
419: TEXT fpenv(SB),$0 /* save floating point environment without waiting */
420: MOVL p+0(FP),AX
421: FSTENV 0(AX)
422: RET
423:
424: /*
425: * special traps
426: */
427: TEXT intr0(SB),$0
428: PUSHL $0
429: PUSHL $0
430: JMP intrcommon
431: TEXT intr1(SB),$0
432: PUSHL $0
433: PUSHL $1
434: JMP intrcommon
435: TEXT intr2(SB),$0
436: PUSHL $0
437: PUSHL $2
438: JMP intrcommon
439: TEXT intr3(SB),$0
440: PUSHL $0
441: PUSHL $3
442: JMP intrcommon
443: TEXT intr4(SB),$0
444: PUSHL $0
445: PUSHL $4
446: JMP intrcommon
447: TEXT intr5(SB),$0
448: PUSHL $0
449: PUSHL $5
450: JMP intrcommon
451: TEXT intr6(SB),$0
452: PUSHL $0
453: PUSHL $6
454: JMP intrcommon
455: TEXT intr7(SB),$0
456: PUSHL $0
457: PUSHL $7
458: JMP intrcommon
459: TEXT intr8(SB),$0
460: PUSHL $8
461: JMP intrscommon
462: TEXT intr9(SB),$0
463: PUSHL $0
464: PUSHL $9
465: JMP intrcommon
466: TEXT intr10(SB),$0
467: PUSHL $10
468: JMP intrscommon
469: TEXT intr11(SB),$0
470: PUSHL $11
471: JMP intrscommon
472: TEXT intr12(SB),$0
473: PUSHL $12
474: JMP intrscommon
475: TEXT intr13(SB),$0
476: PUSHL $13
477: JMP intrscommon
478: TEXT intr14(SB),$0
479: PUSHL $14
480: JMP intrscommon
481: TEXT intr15(SB),$0
482: PUSHL $0
483: PUSHL $15
484: JMP intrcommon
485: TEXT intr16(SB),$0
486: PUSHL $0
487: PUSHL $16
488: JMP intrcommon
489: TEXT intr24(SB),$0
490: PUSHL $0
491: PUSHL $24
492: JMP intrcommon
493: TEXT intr25(SB),$0
494: PUSHL $0
495: PUSHL $25
496: JMP intrcommon
497: TEXT intr26(SB),$0
498: PUSHL $0
499: PUSHL $26
500: JMP intrcommon
501: TEXT intr27(SB),$0
502: PUSHL $0
503: PUSHL $27
504: JMP intrcommon
505: TEXT intr28(SB),$0
506: PUSHL $0
507: PUSHL $28
508: JMP intrcommon
509: TEXT intr29(SB),$0
510: PUSHL $0
511: PUSHL $29
512: JMP intrcommon
513: TEXT intr30(SB),$0
514: PUSHL $0
515: PUSHL $30
516: JMP intrcommon
517: TEXT intr31(SB),$0
518: PUSHL $0
519: PUSHL $31
520: JMP intrcommon
521: TEXT intr32(SB),$0
522: PUSHL $0
523: PUSHL $32
524: JMP intrcommon
525: TEXT intr33(SB),$0
526: PUSHL $0
527: PUSHL $33
528: JMP intrcommon
529: TEXT intr34(SB),$0
530: PUSHL $0
531: PUSHL $34
532: JMP intrcommon
533: TEXT intr35(SB),$0
534: PUSHL $0
535: PUSHL $35
536: JMP intrcommon
537: TEXT intr36(SB),$0
538: PUSHL $0
539: PUSHL $36
540: JMP intrcommon
541: TEXT intr37(SB),$0
542: PUSHL $0
543: PUSHL $37
544: JMP intrcommon
545: TEXT intr38(SB),$0
546: PUSHL $0
547: PUSHL $38
548: JMP intrcommon
549: TEXT intr39(SB),$0
550: PUSHL $0
551: PUSHL $39
552: JMP intrcommon
553: TEXT intr64(SB),$0
554: PUSHL $0
555: PUSHL $64
556: JMP intrcommon
557: TEXT intrbad(SB),$0
558: PUSHL $0
559: PUSHL $0x1ff
560: JMP intrcommon
561:
562: intrcommon:
563: PUSHL DS
564: PUSHL ES
565: PUSHL FS
566: PUSHL GS
567: PUSHAL
568: MOVL $(KDSEL),AX
569: MOVW AX,DS
570: MOVW AX,ES
571: LEAL 0(SP),AX
572: PUSHL AX
573: CALL trap(SB)
574: POPL AX
575: POPAL
576: NOP
577: POPL GS
578: POPL FS
579: POPL ES
580: POPL DS
581: NOP
582: ADDL $8,SP /* error code and trap type */
583: IRETL
584:
585: intrscommon:
586: PUSHL DS
587: PUSHL ES
588: PUSHL FS
589: PUSHL GS
590: PUSHAL
591: MOVL $(KDSEL),AX
592: MOVW AX,DS
593: MOVW AX,ES
594: LEAL 0(SP),AX
595: PUSHL AX
596: CALL trap(SB)
597: POPL AX
598: POPAL
599: NOP
600: POPL GS
601: POPL FS
602: POPL ES
603: POPL DS
604: NOP
605: ADDL $8,SP /* error code and trap type */
606: IRETL
607:
608: /*
609: * interrupt level is interrupts on or off
610: */
611: TEXT spllo(SB),$0
612: PUSHFL
613: POPL AX
614: STI
615: RET
616:
617: TEXT splhi(SB),$0
618: PUSHFL
619: POPL AX
620: CLI
621: RET
622:
623: TEXT splx(SB),$0
624: MOVL s+0(FP),AX
625: PUSHL AX
626: POPFL
627: RET
628:
629: /*
630: * do nothing whatsoever till interrupt happens
631: */
632: TEXT idle(SB),$0
633: HLT
634: RET
635:
636: /*
637: * label consists of a stack pointer and a PC
638: */
639: TEXT gotolabel(SB),$0
640: MOVL l+0(FP),AX
641: MOVL 0(AX),SP /* restore sp */
642: MOVL 4(AX),AX /* put return pc on the stack */
643: MOVL AX,0(SP)
644: MOVL $1,AX /* return 1 */
645: RET
646:
647: TEXT setlabel(SB),$0
648: MOVL l+0(FP),AX
649: MOVL SP,0(AX) /* store sp */
650: MOVL 0(SP),BX /* store return pc */
651: MOVL BX,4(AX)
652: MOVL $0,AX /* return 0 */
653: RET
654:
655: /*
656: * Used to get to the first process.
657: * Set up an interrupt return frame and IRET to user level.
658: */
659: TEXT touser(SB),$0
660: PUSHL $(UDSEL) /* old ss */
661: MOVL sp+0(FP),AX /* old sp */
662: PUSHL AX
663: PUSHFL /* old flags */
664: PUSHL $(UESEL) /* old cs */
665: PUSHL $(UTZERO+32) /* old pc */
666: MOVL $(UDSEL),AX
667: MOVW AX,DS
668: MOVW AX,ES
669: MOVW AX,GS
670: MOVW AX,FS
671: IRETL
672:
673: /*
674: * set configuration register
675: */
676: TEXT config(SB),$0
677: MOVL l+0(FP),AX
678: MOVL $0x3F3,DX
679: OUTB
680: OUTB
681: RET
682:
683: /*
684: * copy bitmap changes to screen memory for ldepth 0 screen.
685: * reverse the bits since the screen is big-endian
686: * and the bitmaps are little.
687: */
688: TEXT l0update(SB),$0
689: MOVL len+8(FP),CX
690: SHRL $1,CX
691: MOVL from+4(FP),SI
692: MOVL to+0(FP),DI
693: XORL AX,AX
694: l00:
695: MOVW -2(SI)(CX*2),DX
696: MOVB DH,AL
697: MOVB revtab0(SB)(AX*1),BX
698: SHLL $8,BX
699: MOVB DL,AL
700: ORB revtab0(SB)(AX*1),BX
701: MOVW BX,-2(DI)(CX*2)
702: LOOP l00
703: RET
704:
705: #define SRX 0x3C4 /* index to sequence registers */
706: #define SR 0x3C5 /* sequence registers */
707: #define Smmask 0x02 /* map mask */
708:
709: /*
710: * same as l0update but for ldepth 1 (2 bit plane) screens
711: */
712: TEXT l1update(SB),$0
713: XORL AX,AX
714: MOVL from+4(FP),SI
715: MOVL to+0(FP),DI
716: MOVL len+8(FP),CX
717: MOVB $(Smmask),AL
718: MOVW $(SRX),DX
719: OUTB
720: l10:
721: MOVL -4(SI)(CX*2),DX
722: MOVB DL,AL
723: MOVL l1revsep(SB)(AX*4),BX
724: SHLL $4,BX
725: RORL $8,DX
726: MOVB DL,AL
727: ORL l1revsep(SB)(AX*4),BX
728: RORL $12,BX
729: RORL $8,DX
730: MOVB DL,AL
731: ORL l1revsep(SB)(AX*4),BX
732: SHLL $4,BX
733: RORL $8,DX
734: MOVB DL,AL
735: ORL l1revsep(SB)(AX*4),BX
736: ROLL $8,BX
737: MOVW $(SR),DX
738: MOVB $0x5,AL /* write lo order bits to bit planes 1 & 3 */
739: OUTB
740: MOVW BX,-2(DI)(CX*1)
741: SHRL $16,BX /* write hi order bits to bit planes 0 & 2 */
742: MOVB $0xA,AL
743: OUTB
744: MOVW BX,-2(DI)(CX*1)
745: LOOP l10
746: RET
747:
748: /*
749: * same as l0update but for ldepth 2 (4 bit plane) screens
750: */
751: TEXT l2update(SB),$0
752: XORL AX,AX
753: MOVL from+4(FP),SI
754: MOVL to+0(FP),DI
755: MOVL len+8(FP),CX
756: MOVB $(Smmask),AL
757: MOVW $(SRX),DX
758: OUTB
759: l20:
760: MOVL -4(SI)(CX*4),DX
761: MOVB DL,AL
762: MOVL l2revsep(SB)(AX*4),BX
763: SHLL $2,BX
764: SHRL $8,DX
765: MOVB DL,AL
766: ORL l2revsep(SB)(AX*4),BX
767: SHLL $2,BX
768: SHRL $8,DX
769: MOVB DL,AL
770: ORL l2revsep(SB)(AX*4),BX
771: SHLL $2,BX
772: SHRL $8,DX
773: MOVB DL,AL
774: ORL l2revsep(SB)(AX*4),BX
775: MOVW $(SR),DX
776: MOVB $0x1,AL /* plane 3 */
777: OUTB
778: MOVB BX,-1(DI)(CX*1)
779: MOVB $0x2,AL /* plane 2 */
780: OUTB
781: SHRL $8,BX
782: MOVB BX,-1(DI)(CX*1)
783: MOVB $0x4,AL /* plane 1 */
784: OUTB
785: SHRL $8,BX
786: MOVB BX,-1(DI)(CX*1)
787: MOVB $0x8,AL /* plane 0*/
788: OUTB
789: SHRL $8,BX
790: MOVB BX,-1(DI)(CX*1)
791: LOOP l20
792: RET
793:
794: /*
795: * The DP8390 ethernet chip needs some time between
796: * successive chip selects, so we force a jump into
797: * the instruction stream to break the pipeline.
798: */
799: TEXT dp8390inb(SB), $0
800: MOVL p+0(FP),DX
801: XORL AX,AX /* CF = 0 */
802: INB
803:
804: JCC _dp8390inb0 /* always true */
805: MOVL AX,AX
806:
807: _dp8390inb0:
808: RET
809:
810: TEXT dp8390outb(SB), $0
811: MOVL p+0(FP),DX
812: MOVL b+4(FP),AX
813: OUTB
814:
815: CLC /* CF = 0 */
816: JCC _dp8390outb0 /* always true */
817: MOVL AX,AX
818:
819: _dp8390outb0:
820: RET
821:
822: /*
823: * dsp outb string called from devdsp.c
824: */
825: TEXT dspoutb+0(SB), $0
826:
827: MOVL a+4(FP), BX
828: MOVL n+8(FP), CX
829:
830: MOVL base+0(FP), DX
831: ADDL $2, DX /* Pcontrol */
832:
833: MOVL c2+12(FP), DI
834: MOVL c3+16(FP), SI
835:
836: dsploop:
837: MOVL DI, AX /* normal */
838: OUTB
839:
840: SUBL $1, CX
841: CMPL CX, $0
842: JLT dspout
843:
844: SUBL $2, DX /* Pdata */
845: MOVB (BX), AX
846: ADDL $1, BX
847: OUTB
848:
849: ADDL $2, DX /* Pcontrol */
850: MOVL SI, AX /* strobe */
851: OUTB
852:
853: JMP dsploop
854:
855: dspout:
856: RET
857:
858:
859: /*
860: * return cpu type (586 == pentium or better)
861: */
862: TEXT x86cpuid(SB),$0
863:
864: PUSHFL
865: MOVL 0(SP),AX
866: XORL $0x240000,AX
867: PUSHL AX
868: POPFL
869: PUSHFL
870: MOVL 0(SP),AX
871: XORL 4(SP),AX
872: MOVL AX, BX
873: ANDL $0x40000,BX /* on 386 we can't change this bit */
874: JZ is386
875: ANDL $0x200000,AX /* if we can't change this, there's no CPUID */
876: JZ is486
877: MOVL $1,AX
878: /* CPUID */
879: BYTE $0x0F
880: BYTE $0xA2
881: JMP done
882: is486:
883: MOVL $(4<<8),AX
884: MOVL $0,DX
885: JMP done
886: is386:
887: MOVL $(3<<8),AX
888: MOVL $0,DX
889: done:
890: MOVL a+0(FP),CX
891: MOVL AX,0(CX)
892: MOVL d+4(FP),CX
893: MOVL DX,0(CX)
894: POPFL
895: POPL BX
896: RET
897:
898: /*
899: * basic timing loop to determine CPU frequency
900: */
901: TEXT aamloop(SB),$0
902:
903: MOVL c+0(FP),CX
904: aaml1:
905: AAM
906: LOOP aaml1
907: RET
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.