l.s 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933
  1. #include "mem.h"
  2. #define PADDR(a) ((a) & ~KZERO)
  3. #define KADDR(a) (KZERO|(a))
  4. /*
  5. * Some machine instructions not handled by 8[al].
  6. */
  7. #define OP16 BYTE $0x66
  8. #define DELAY BYTE $0xEB; BYTE $0x00 /* JMP .+2 */
  9. #define CPUID BYTE $0x0F; BYTE $0xA2 /* CPUID, argument in AX */
  10. #define WRMSR BYTE $0x0F; BYTE $0x30 /* WRMSR, argument in AX/DX (lo/hi) */
  11. #define RDTSC BYTE $0x0F; BYTE $0x31 /* RDTSC, result in AX/DX (lo/hi) */
  12. #define RDMSR BYTE $0x0F; BYTE $0x32 /* RDMSR, result in AX/DX (lo/hi) */
  13. #define WBINVD BYTE $0x0F; BYTE $0x09
  14. #define HLT BYTE $0xF4
  15. /*
  16. * Macros for calculating offsets within the page directory base
  17. * and page tables. Note that these are assembler-specific hence
  18. * the '<<2'.
  19. */
  20. #define PDO(a) (((((a))>>22) & 0x03FF)<<2)
  21. #define PTO(a) (((((a))>>12) & 0x03FF)<<2)
  22. /*
  23. * For backwards compatiblity with 9load - should go away when 9load is changed
  24. * 9load currently sets up the mmu, however the first 16MB of memory is identity
  25. * mapped, so behave as if the mmu was not setup
  26. */
  27. TEXT _start0x80100020(SB), $0
  28. MOVL $_start0x00100020(SB), AX
  29. ANDL $~KZERO, AX
  30. JMP* AX
  31. /*
  32. * In protected mode with paging turned off and segment registers setup to linear map all memory.
  33. * Entered via a jump to 0x00100020, the physical address of the virtual kernel entry point of 0x80100020
  34. * Make the basic page tables for processor 0. Four pages are needed for the basic set:
  35. * a page directory, a page table for mapping the first 4MB of physical memory to KZERO,
  36. * and virtual and physical pages for mapping the Mach structure.
  37. * The remaining PTEs will be allocated later when memory is sized.
  38. * An identity mmu map is also needed for the switch to virtual mode. This
  39. * identity mapping is removed once the MMU is going and the JMP has been made
  40. * to virtual memory.
  41. */
  42. TEXT _start0x00100020(SB), $0
  43. CLI /* make sure interrupts are off */
  44. /* set up the gdt so we have sane plan 9 style gdts. */
  45. MOVL $tgdtptr(SB), AX
  46. ANDL $~KZERO, AX
  47. MOVL (AX), GDTR
  48. MOVW $1, AX
  49. MOVW AX, MSW
  50. /* clear prefetch queue (weird code to avoid optimizations) */
  51. DELAY
  52. /* set segs to something sane (avoid traps later) */
  53. MOVW $(1<<3), AX
  54. MOVW AX, DS
  55. MOVW AX, SS
  56. MOVW AX, ES
  57. MOVW AX, FS
  58. MOVW AX, GS
  59. /* JMP $(2<<3):$mode32bit(SB) /**/
  60. BYTE $0xEA
  61. LONG $mode32bit-KZERO(SB)
  62. WORD $(2<<3)
  63. /*
  64. * gdt to get us to 32-bit/segmented/unpaged mode
  65. */
  66. TEXT tgdt(SB), $0
  67. /* null descriptor */
  68. LONG $0
  69. LONG $0
  70. /* data segment descriptor for 4 gigabytes (PL 0) */
  71. LONG $(0xFFFF)
  72. LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
  73. /* exec segment descriptor for 4 gigabytes (PL 0) */
  74. LONG $(0xFFFF)
  75. LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
  76. /*
  77. * pointer to initial gdt
  78. * Note the -KZERO which puts the physical address in the gdtptr.
  79. * that's needed as we start executing in physical addresses.
  80. */
  81. TEXT tgdtptr(SB), $0
  82. WORD $(3*8)
  83. LONG $tgdt-KZERO(SB)
  84. TEXT mode32bit(SB), $0
  85. /* At this point, the GDT setup is done. */
  86. MOVL $PADDR(CPU0PDB), DI /* clear 4 pages for the tables etc. */
  87. XORL AX, AX
  88. MOVL $(4*BY2PG), CX
  89. SHRL $2, CX
  90. CLD
  91. REP; STOSL
  92. MOVL $PADDR(CPU0PDB), AX
  93. ADDL $PDO(KZERO), AX /* page directory offset for KZERO */
  94. MOVL $PADDR(CPU0PTE), (AX) /* PTE's for 0x80000000 */
  95. MOVL $(PTEWRITE|PTEVALID), BX /* page permissions */
  96. ORL BX, (AX)
  97. MOVL $PADDR(CPU0PTE), AX /* first page of page table */
  98. MOVL $1024, CX /* 1024 pages in 4MB */
  99. _setpte:
  100. MOVL BX, (AX)
  101. ADDL $(1<<PGSHIFT), BX
  102. ADDL $4, AX
  103. LOOP _setpte
  104. MOVL $PADDR(CPU0PTE), AX
  105. ADDL $PTO(MACHADDR), AX /* page table entry offset for MACHADDR */
  106. MOVL $PADDR(CPU0MACH), (AX) /* PTE for Mach */
  107. MOVL $(PTEWRITE|PTEVALID), BX /* page permissions */
  108. ORL BX, (AX)
  109. /*
  110. * Now ready to use the new map. Make sure the processor options are what is wanted.
  111. * It is necessary on some processors to immediately follow mode switching with a JMP instruction
  112. * to clear the prefetch queues.
  113. */
  114. MOVL $PADDR(CPU0PDB), CX /* load address of page directory */
  115. MOVL (PDO(KZERO))(CX), DX /* double-map KZERO at 0 */
  116. MOVL DX, (PDO(0))(CX)
  117. MOVL CX, CR3
  118. DELAY /* JMP .+2 */
  119. MOVL CR0, DX
  120. ORL $0x80010000, DX /* PG|WP */
  121. ANDL $~0x6000000A, DX /* ~(CD|NW|TS|MP) */
  122. MOVL $_startpg(SB), AX /* this is a virtual address */
  123. MOVL DX, CR0 /* turn on paging */
  124. JMP* AX /* jump to the virtual nirvana */
  125. /*
  126. * Basic machine environment set, can clear BSS and create a stack.
  127. * The stack starts at the top of the page containing the Mach structure.
  128. * The x86 architecture forces the use of the same virtual address for
  129. * each processor's Mach structure, so the global Mach pointer 'm' can
  130. * be initialised here.
  131. */
  132. TEXT _startpg(SB), $0
  133. MOVL $0, (PDO(0))(CX) /* undo double-map of KZERO at 0 */
  134. MOVL CX, CR3 /* load and flush the mmu */
  135. _clearbss:
  136. MOVL $edata(SB), DI
  137. XORL AX, AX
  138. MOVL $end(SB), CX
  139. SUBL DI, CX /* end-edata bytes */
  140. SHRL $2, CX /* end-edata doublewords */
  141. CLD
  142. REP; STOSL /* clear BSS */
  143. MOVL $MACHADDR, SP
  144. MOVL SP, m(SB) /* initialise global Mach pointer */
  145. MOVL $0, 0(SP) /* initialise m->machno */
  146. ADDL $(MACHSIZE-4), SP /* initialise stack */
  147. /*
  148. * Need to do one final thing to ensure a clean machine environment,
  149. * clear the EFLAGS register, which can only be done once there is a stack.
  150. */
  151. MOVL $0, AX
  152. PUSHL AX
  153. POPFL
  154. CALL main(SB)
  155. /*
  156. * Park a processor. Should never fall through a return from main to here,
  157. * should only be called by application processors when shutting down.
  158. */
  159. TEXT idle(SB), $0
  160. _idle:
  161. STI
  162. HLT
  163. JMP _idle
  164. /*
  165. * Port I/O.
  166. * in[bsl] input a byte|short|long
  167. * ins[bsl] input a string of bytes|shorts|longs
  168. * out[bsl] output a byte|short|long
  169. * outs[bsl] output a string of bytes|shorts|longs
  170. */
  171. TEXT inb(SB), $0
  172. MOVL port+0(FP), DX
  173. XORL AX, AX
  174. INB
  175. RET
  176. TEXT insb(SB), $0
  177. MOVL port+0(FP), DX
  178. MOVL address+4(FP), DI
  179. MOVL count+8(FP), CX
  180. CLD
  181. REP; INSB
  182. RET
  183. TEXT ins(SB), $0
  184. MOVL port+0(FP), DX
  185. XORL AX, AX
  186. OP16; INL
  187. RET
  188. TEXT inss(SB), $0
  189. MOVL port+0(FP), DX
  190. MOVL address+4(FP), DI
  191. MOVL count+8(FP), CX
  192. CLD
  193. REP; OP16; INSL
  194. RET
  195. TEXT inl(SB), $0
  196. MOVL port+0(FP), DX
  197. INL
  198. RET
  199. TEXT insl(SB), $0
  200. MOVL port+0(FP), DX
  201. MOVL address+4(FP), DI
  202. MOVL count+8(FP), CX
  203. CLD
  204. REP; INSL
  205. RET
  206. TEXT outb(SB), $0
  207. MOVL port+0(FP), DX
  208. MOVL byte+4(FP), AX
  209. OUTB
  210. RET
  211. TEXT outsb(SB), $0
  212. MOVL port+0(FP), DX
  213. MOVL address+4(FP), SI
  214. MOVL count+8(FP), CX
  215. CLD
  216. REP; OUTSB
  217. RET
  218. TEXT outs(SB), $0
  219. MOVL port+0(FP), DX
  220. MOVL short+4(FP), AX
  221. OP16; OUTL
  222. RET
  223. TEXT outss(SB), $0
  224. MOVL port+0(FP), DX
  225. MOVL address+4(FP), SI
  226. MOVL count+8(FP), CX
  227. CLD
  228. REP; OP16; OUTSL
  229. RET
  230. TEXT outl(SB), $0
  231. MOVL port+0(FP), DX
  232. MOVL long+4(FP), AX
  233. OUTL
  234. RET
  235. TEXT outsl(SB), $0
  236. MOVL port+0(FP), DX
  237. MOVL address+4(FP), SI
  238. MOVL count+8(FP), CX
  239. CLD
  240. REP; OUTSL
  241. RET
  242. /*
  243. * Read/write various system registers.
  244. * CR4 and the 'model specific registers' should only be read/written
  245. * after it has been determined the processor supports them
  246. */
  247. TEXT lgdt(SB), $0 /* GDTR - global descriptor table */
  248. MOVL gdtptr+0(FP), AX
  249. MOVL (AX), GDTR
  250. RET
  251. TEXT lidt(SB), $0 /* IDTR - interrupt descriptor table */
  252. MOVL idtptr+0(FP), AX
  253. MOVL (AX), IDTR
  254. RET
  255. TEXT ltr(SB), $0 /* TR - task register */
  256. MOVL tptr+0(FP), AX
  257. MOVW AX, TASK
  258. RET
  259. TEXT getcr0(SB), $0 /* CR0 - processor control */
  260. MOVL CR0, AX
  261. RET
  262. TEXT getcr2(SB), $0 /* CR2 - page fault linear address */
  263. MOVL CR2, AX
  264. RET
  265. TEXT getcr3(SB), $0 /* CR3 - page directory base */
  266. MOVL CR3, AX
  267. RET
  268. TEXT putcr3(SB), $0
  269. MOVL cr3+0(FP), AX
  270. MOVL AX, CR3
  271. RET
  272. TEXT getcr4(SB), $0 /* CR4 - extensions */
  273. MOVL CR4, AX
  274. RET
  275. TEXT putcr4(SB), $0
  276. MOVL cr4+0(FP), AX
  277. MOVL AX, CR4
  278. RET
  279. TEXT cycles(SB), $0 /* time stamp counter; cycles since power up */
  280. RDTSC
  281. MOVL vlong+0(FP), CX /* &vlong */
  282. MOVL AX, 0(CX) /* lo */
  283. MOVL DX, 4(CX) /* hi */
  284. RET
  285. TEXT rdmsr(SB), $0 /* model-specific register */
  286. MOVL index+0(FP), CX
  287. RDMSR
  288. MOVL vlong+4(FP), CX /* &vlong */
  289. MOVL AX, 0(CX) /* lo */
  290. MOVL DX, 4(CX) /* hi */
  291. RET
  292. TEXT wrmsr(SB), $0
  293. MOVL index+0(FP), CX
  294. MOVL lo+4(FP), AX
  295. MOVL hi+8(FP), DX
  296. WRMSR
  297. RET
  298. TEXT wbinvd(SB), $0
  299. WBINVD
  300. RET
  301. /*
  302. * Try to determine the CPU type which requires fiddling with EFLAGS.
  303. * If the Id bit can be toggled then the CPUID instruciton can be used
  304. * to determine CPU identity and features. First have to check if it's
  305. * a 386 (Ac bit can't be set). If it's not a 386 and the Id bit can't be
  306. * toggled then it's an older 486 of some kind.
  307. *
  308. * cpuid(id[], &ax, &dx);
  309. */
  310. TEXT cpuid(SB), $0
  311. MOVL $0x240000, AX
  312. PUSHL AX
  313. POPFL /* set Id|Ac */
  314. PUSHFL
  315. POPL BX /* retrieve value */
  316. MOVL $0, AX
  317. PUSHL AX
  318. POPFL /* clear Id|Ac, EFLAGS initialised */
  319. PUSHFL
  320. POPL AX /* retrieve value */
  321. XORL BX, AX
  322. TESTL $0x040000, AX /* Ac */
  323. JZ _cpu386 /* can't set this bit on 386 */
  324. TESTL $0x200000, AX /* Id */
  325. JZ _cpu486 /* can't toggle this bit on some 486 */
  326. MOVL $0, AX
  327. CPUID
  328. MOVL id+0(FP), BP
  329. MOVL BX, 0(BP) /* "Genu" "Auth" "Cyri" */
  330. MOVL DX, 4(BP) /* "ineI" "enti" "xIns" */
  331. MOVL CX, 8(BP) /* "ntel" "cAMD" "tead" */
  332. MOVL $1, AX
  333. CPUID
  334. JMP _cpuid
  335. _cpu486:
  336. MOVL $0x400, AX
  337. MOVL $0, DX
  338. JMP _cpuid
  339. _cpu386:
  340. MOVL $0x300, AX
  341. MOVL $0, DX
  342. _cpuid:
  343. MOVL ax+4(FP), BP
  344. MOVL AX, 0(BP)
  345. MOVL dx+8(FP), BP
  346. MOVL DX, 0(BP)
  347. RET
  348. /*
  349. * Basic timing loop to determine CPU frequency.
  350. */
  351. TEXT aamloop(SB), $0
  352. MOVL count+0(FP), CX
  353. _aamloop:
  354. AAM
  355. LOOP _aamloop
  356. RET
  357. /*
  358. * Floating point.
  359. */
  360. #define FPOFF ;\
  361. WAIT ;\
  362. MOVL CR0, AX ;\
  363. ANDL $~0x4, AX /* EM=0 */ ;\
  364. ORL $0x28, AX /* NE=1, TS=1 */ ;\
  365. MOVL AX, CR0
  366. #define FPON ;\
  367. MOVL CR0, AX ;\
  368. ANDL $~0xC, AX /* EM=0, TS=0 */ ;\
  369. MOVL AX, CR0
  370. TEXT fpoff(SB), $0 /* disable */
  371. FPOFF
  372. RET
  373. TEXT fpinit(SB), $0 /* enable and init */
  374. FPON
  375. FINIT
  376. WAIT
  377. /* setfcr(FPPDBL|FPRNR|FPINVAL|FPZDIV|FPOVFL) */
  378. /* note that low 6 bits are masks, not enables, on this chip */
  379. PUSHW $0x0232
  380. FLDCW 0(SP)
  381. POPW AX
  382. WAIT
  383. RET
  384. TEXT fpsave(SB), $0 /* save state and disable */
  385. MOVL p+0(FP), AX
  386. FSAVE 0(AX) /* no WAIT */
  387. FPOFF
  388. RET
  389. TEXT fprestore(SB), $0 /* enable and restore state */
  390. FPON
  391. MOVL p+0(FP), AX
  392. FRSTOR 0(AX)
  393. WAIT
  394. RET
  395. TEXT fpstatus(SB), $0 /* get floating point status */
  396. FSTSW AX
  397. RET
  398. TEXT fpenv(SB), $0 /* save state without waiting */
  399. MOVL p+0(FP), AX
  400. FSTENV 0(AX)
  401. RET
  402. /*
  403. */
  404. TEXT splhi(SB), $0
  405. MOVL $(MACHADDR+0x04), AX /* save PC in m->splpc */
  406. MOVL (SP), BX
  407. MOVL BX, (AX)
  408. PUSHFL
  409. POPL AX
  410. CLI
  411. RET
  412. TEXT spllo(SB), $0
  413. PUSHFL
  414. POPL AX
  415. STI
  416. RET
  417. TEXT splx(SB), $0
  418. MOVL $(MACHADDR+0x04), AX /* save PC in m->splpc */
  419. MOVL (SP), BX
  420. MOVL BX, (AX)
  421. /*FALLTHROUGH*/
  422. TEXT splxpc(SB), $0 /* for iunlock */
  423. MOVL s+0(FP), AX
  424. PUSHL AX
  425. POPFL
  426. RET
  427. TEXT spldone(SB), $0
  428. RET
  429. TEXT islo(SB), $0
  430. PUSHFL
  431. POPL AX
  432. ANDL $0x200, AX /* interrupt enable flag */
  433. RET
  434. /*
  435. * Test-And-Set
  436. */
  437. TEXT tas(SB), $0
  438. MOVL $0xDEADDEAD, AX
  439. MOVL lock+0(FP), BX
  440. XCHGL AX, (BX) /* lock->key */
  441. RET
  442. TEXT _xinc(SB), $0 /* void _xinc(long*); */
  443. MOVL l+0(FP), AX
  444. LOCK; INCL 0(AX)
  445. RET
  446. TEXT _xdec(SB), $0 /* long _xdec(long*); */
  447. MOVL l+0(FP), BX
  448. XORL AX, AX
  449. LOCK; DECL 0(BX)
  450. JLT _xdeclt
  451. JGT _xdecgt
  452. RET
  453. _xdecgt:
  454. INCL AX
  455. RET
  456. _xdeclt:
  457. DECL AX
  458. RET
  459. TEXT wbflush(SB), $0
  460. CPUID
  461. RET
  462. TEXT xchgw(SB), $0
  463. MOVL v+4(FP), AX
  464. MOVL p+0(FP), BX
  465. XCHGW AX, (BX)
  466. RET
  467. /*
  468. * mul64fract(uvlong* r, uvlong a, uvlong b)
  469. *
  470. * multiply uvlong a by uvlong b and return a uvlong result.
  471. *
  472. * One of the input arguments is a uvlong integer,
  473. * the other represents a fractional number with
  474. * the integer portion in the most significant word and
  475. * the fractional portion in the least significant word.
  476. *
  477. * Example: mul64fract(&r, 2ULL, 3ULL << 31) returns 1ULL
  478. *
  479. * The uvlong integer result is returned through r
  480. *
  481. * ignored r0 = lo(a0*b0)
  482. * lsw of result r1 = hi(a0*b0) +lo(a0*b1) +lo(a1*b0)
  483. * msw of result r2 = hi(a0*b1) +hi(a1*b0) +lo(a1*b1)
  484. * ignored r3 = hi(a1*b1)
  485. */
  486. TEXT mul64fract(SB), $0
  487. MOVL r+0(FP), CX
  488. XORL BX, BX /* BX = 0 */
  489. MOVL a+8(FP), AX
  490. MULL b+16(FP) /* a1*b1 */
  491. MOVL AX, 4(CX) /* r2 = lo(a1*b1) */
  492. MOVL a+8(FP), AX
  493. MULL b+12(FP) /* a1*b0 */
  494. MOVL AX, 0(CX) /* r1 = lo(a1*b0) */
  495. ADDL DX, 4(CX) /* r2 += hi(a1*b0) */
  496. MOVL a+4(FP), AX
  497. MULL b+16(FP) /* a0*b1 */
  498. ADDL AX, 0(CX) /* r1 += lo(a0*b1) */
  499. ADCL DX, 4(CX) /* r2 += hi(a0*b1) + carry */
  500. MOVL a+4(FP), AX
  501. MULL b+12(FP) /* a0*b0 */
  502. ADDL DX, 0(CX) /* r1 += hi(a0*b0) */
  503. ADCL BX, 4(CX) /* r2 += carry */
  504. RET
  505. /*
  506. * label consists of a stack pointer and a PC
  507. */
  508. TEXT gotolabel(SB), $0
  509. MOVL label+0(FP), AX
  510. MOVL 0(AX), SP /* restore sp */
  511. MOVL 4(AX), AX /* put return pc on the stack */
  512. MOVL AX, 0(SP)
  513. MOVL $1, AX /* return 1 */
  514. RET
  515. TEXT setlabel(SB), $0
  516. MOVL label+0(FP), AX
  517. MOVL SP, 0(AX) /* store sp */
  518. MOVL 0(SP), BX /* store return pc */
  519. MOVL BX, 4(AX)
  520. MOVL $0, AX /* return 0 */
  521. RET
  522. /*
  523. * Attempt at power saving. -rsc
  524. */
  525. TEXT halt(SB), $0
  526. CLI
  527. CMPL nrdy(SB), $0
  528. JEQ _nothingready
  529. STI
  530. RET
  531. _nothingready:
  532. STI
  533. HLT
  534. RET
  535. /*
  536. * Interrupt/exception handling.
  537. * Each entry in the vector table calls either _strayintr or _strayintrx depending
  538. * on whether an error code has been automatically pushed onto the stack
  539. * (_strayintrx) or not, in which case a dummy entry must be pushed before retrieving
  540. * the trap type from the vector table entry and placing it on the stack as part
  541. * of the Ureg structure.
  542. * The size of each entry in the vector table (6 bytes) is known in trapinit().
  543. */
  544. TEXT _strayintr(SB), $0
  545. PUSHL AX /* save AX */
  546. MOVL 4(SP), AX /* return PC from vectortable(SB) */
  547. JMP intrcommon
  548. TEXT _strayintrx(SB), $0
  549. XCHGL AX, (SP) /* swap AX with vectortable CALL PC */
  550. intrcommon:
  551. PUSHL DS /* save DS */
  552. PUSHL $(KDSEL)
  553. POPL DS /* fix up DS */
  554. MOVBLZX (AX), AX /* trap type -> AX */
  555. XCHGL AX, 4(SP) /* exchange trap type with saved AX */
  556. PUSHL ES /* save ES */
  557. PUSHL $(KDSEL)
  558. POPL ES /* fix up ES */
  559. PUSHL FS /* save the rest of the Ureg struct */
  560. PUSHL GS
  561. PUSHAL
  562. PUSHL SP /* Ureg* argument to trap */
  563. CALL trap(SB)
  564. TEXT forkret(SB), $0
  565. POPL AX
  566. POPAL
  567. POPL GS
  568. POPL FS
  569. POPL ES
  570. POPL DS
  571. ADDL $8, SP /* pop error code and trap type */
  572. IRETL
  573. TEXT vectortable(SB), $0
  574. CALL _strayintr(SB); BYTE $0x00 /* divide error */
  575. CALL _strayintr(SB); BYTE $0x01 /* debug exception */
  576. CALL _strayintr(SB); BYTE $0x02 /* NMI interrupt */
  577. CALL _strayintr(SB); BYTE $0x03 /* breakpoint */
  578. CALL _strayintr(SB); BYTE $0x04 /* overflow */
  579. CALL _strayintr(SB); BYTE $0x05 /* bound */
  580. CALL _strayintr(SB); BYTE $0x06 /* invalid opcode */
  581. CALL _strayintr(SB); BYTE $0x07 /* no coprocessor available */
  582. CALL _strayintrx(SB); BYTE $0x08 /* double fault */
  583. CALL _strayintr(SB); BYTE $0x09 /* coprocessor segment overflow */
  584. CALL _strayintrx(SB); BYTE $0x0A /* invalid TSS */
  585. CALL _strayintrx(SB); BYTE $0x0B /* segment not available */
  586. CALL _strayintrx(SB); BYTE $0x0C /* stack exception */
  587. CALL _strayintrx(SB); BYTE $0x0D /* general protection error */
  588. CALL _strayintrx(SB); BYTE $0x0E /* page fault */
  589. CALL _strayintr(SB); BYTE $0x0F /* */
  590. CALL _strayintr(SB); BYTE $0x10 /* coprocessor error */
  591. CALL _strayintrx(SB); BYTE $0x11 /* alignment check */
  592. CALL _strayintr(SB); BYTE $0x12 /* machine check */
  593. CALL _strayintr(SB); BYTE $0x13
  594. CALL _strayintr(SB); BYTE $0x14
  595. CALL _strayintr(SB); BYTE $0x15
  596. CALL _strayintr(SB); BYTE $0x16
  597. CALL _strayintr(SB); BYTE $0x17
  598. CALL _strayintr(SB); BYTE $0x18
  599. CALL _strayintr(SB); BYTE $0x19
  600. CALL _strayintr(SB); BYTE $0x1A
  601. CALL _strayintr(SB); BYTE $0x1B
  602. CALL _strayintr(SB); BYTE $0x1C
  603. CALL _strayintr(SB); BYTE $0x1D
  604. CALL _strayintr(SB); BYTE $0x1E
  605. CALL _strayintr(SB); BYTE $0x1F
  606. CALL _strayintr(SB); BYTE $0x20 /* VectorLAPIC */
  607. CALL _strayintr(SB); BYTE $0x21
  608. CALL _strayintr(SB); BYTE $0x22
  609. CALL _strayintr(SB); BYTE $0x23
  610. CALL _strayintr(SB); BYTE $0x24
  611. CALL _strayintr(SB); BYTE $0x25
  612. CALL _strayintr(SB); BYTE $0x26
  613. CALL _strayintr(SB); BYTE $0x27
  614. CALL _strayintr(SB); BYTE $0x28
  615. CALL _strayintr(SB); BYTE $0x29
  616. CALL _strayintr(SB); BYTE $0x2A
  617. CALL _strayintr(SB); BYTE $0x2B
  618. CALL _strayintr(SB); BYTE $0x2C
  619. CALL _strayintr(SB); BYTE $0x2D
  620. CALL _strayintr(SB); BYTE $0x2E
  621. CALL _strayintr(SB); BYTE $0x2F
  622. CALL _strayintr(SB); BYTE $0x30
  623. CALL _strayintr(SB); BYTE $0x31
  624. CALL _strayintr(SB); BYTE $0x32
  625. CALL _strayintr(SB); BYTE $0x33
  626. CALL _strayintr(SB); BYTE $0x34
  627. CALL _strayintr(SB); BYTE $0x35
  628. CALL _strayintr(SB); BYTE $0x36
  629. CALL _strayintr(SB); BYTE $0x37
  630. CALL _strayintr(SB); BYTE $0x38
  631. CALL _strayintr(SB); BYTE $0x39
  632. CALL _strayintr(SB); BYTE $0x3A
  633. CALL _strayintr(SB); BYTE $0x3B
  634. CALL _strayintr(SB); BYTE $0x3C
  635. CALL _strayintr(SB); BYTE $0x3D
  636. CALL _strayintr(SB); BYTE $0x3E
  637. CALL _strayintr(SB); BYTE $0x3F
  638. CALL _syscallintr(SB); BYTE $0x40 /* VectorSYSCALL */
  639. CALL _strayintr(SB); BYTE $0x41
  640. CALL _strayintr(SB); BYTE $0x42
  641. CALL _strayintr(SB); BYTE $0x43
  642. CALL _strayintr(SB); BYTE $0x44
  643. CALL _strayintr(SB); BYTE $0x45
  644. CALL _strayintr(SB); BYTE $0x46
  645. CALL _strayintr(SB); BYTE $0x47
  646. CALL _strayintr(SB); BYTE $0x48
  647. CALL _strayintr(SB); BYTE $0x49
  648. CALL _strayintr(SB); BYTE $0x4A
  649. CALL _strayintr(SB); BYTE $0x4B
  650. CALL _strayintr(SB); BYTE $0x4C
  651. CALL _strayintr(SB); BYTE $0x4D
  652. CALL _strayintr(SB); BYTE $0x4E
  653. CALL _strayintr(SB); BYTE $0x4F
  654. CALL _strayintr(SB); BYTE $0x50
  655. CALL _strayintr(SB); BYTE $0x51
  656. CALL _strayintr(SB); BYTE $0x52
  657. CALL _strayintr(SB); BYTE $0x53
  658. CALL _strayintr(SB); BYTE $0x54
  659. CALL _strayintr(SB); BYTE $0x55
  660. CALL _strayintr(SB); BYTE $0x56
  661. CALL _strayintr(SB); BYTE $0x57
  662. CALL _strayintr(SB); BYTE $0x58
  663. CALL _strayintr(SB); BYTE $0x59
  664. CALL _strayintr(SB); BYTE $0x5A
  665. CALL _strayintr(SB); BYTE $0x5B
  666. CALL _strayintr(SB); BYTE $0x5C
  667. CALL _strayintr(SB); BYTE $0x5D
  668. CALL _strayintr(SB); BYTE $0x5E
  669. CALL _strayintr(SB); BYTE $0x5F
  670. CALL _strayintr(SB); BYTE $0x60
  671. CALL _strayintr(SB); BYTE $0x61
  672. CALL _strayintr(SB); BYTE $0x62
  673. CALL _strayintr(SB); BYTE $0x63
  674. CALL _strayintr(SB); BYTE $0x64
  675. CALL _strayintr(SB); BYTE $0x65
  676. CALL _strayintr(SB); BYTE $0x66
  677. CALL _strayintr(SB); BYTE $0x67
  678. CALL _strayintr(SB); BYTE $0x68
  679. CALL _strayintr(SB); BYTE $0x69
  680. CALL _strayintr(SB); BYTE $0x6A
  681. CALL _strayintr(SB); BYTE $0x6B
  682. CALL _strayintr(SB); BYTE $0x6C
  683. CALL _strayintr(SB); BYTE $0x6D
  684. CALL _strayintr(SB); BYTE $0x6E
  685. CALL _strayintr(SB); BYTE $0x6F
  686. CALL _strayintr(SB); BYTE $0x70
  687. CALL _strayintr(SB); BYTE $0x71
  688. CALL _strayintr(SB); BYTE $0x72
  689. CALL _strayintr(SB); BYTE $0x73
  690. CALL _strayintr(SB); BYTE $0x74
  691. CALL _strayintr(SB); BYTE $0x75
  692. CALL _strayintr(SB); BYTE $0x76
  693. CALL _strayintr(SB); BYTE $0x77
  694. CALL _strayintr(SB); BYTE $0x78
  695. CALL _strayintr(SB); BYTE $0x79
  696. CALL _strayintr(SB); BYTE $0x7A
  697. CALL _strayintr(SB); BYTE $0x7B
  698. CALL _strayintr(SB); BYTE $0x7C
  699. CALL _strayintr(SB); BYTE $0x7D
  700. CALL _strayintr(SB); BYTE $0x7E
  701. CALL _strayintr(SB); BYTE $0x7F
  702. CALL _strayintr(SB); BYTE $0x80 /* Vector[A]PIC */
  703. CALL _strayintr(SB); BYTE $0x81
  704. CALL _strayintr(SB); BYTE $0x82
  705. CALL _strayintr(SB); BYTE $0x83
  706. CALL _strayintr(SB); BYTE $0x84
  707. CALL _strayintr(SB); BYTE $0x85
  708. CALL _strayintr(SB); BYTE $0x86
  709. CALL _strayintr(SB); BYTE $0x87
  710. CALL _strayintr(SB); BYTE $0x88
  711. CALL _strayintr(SB); BYTE $0x89
  712. CALL _strayintr(SB); BYTE $0x8A
  713. CALL _strayintr(SB); BYTE $0x8B
  714. CALL _strayintr(SB); BYTE $0x8C
  715. CALL _strayintr(SB); BYTE $0x8D
  716. CALL _strayintr(SB); BYTE $0x8E
  717. CALL _strayintr(SB); BYTE $0x8F
  718. CALL _strayintr(SB); BYTE $0x90
  719. CALL _strayintr(SB); BYTE $0x91
  720. CALL _strayintr(SB); BYTE $0x92
  721. CALL _strayintr(SB); BYTE $0x93
  722. CALL _strayintr(SB); BYTE $0x94
  723. CALL _strayintr(SB); BYTE $0x95
  724. CALL _strayintr(SB); BYTE $0x96
  725. CALL _strayintr(SB); BYTE $0x97
  726. CALL _strayintr(SB); BYTE $0x98
  727. CALL _strayintr(SB); BYTE $0x99
  728. CALL _strayintr(SB); BYTE $0x9A
  729. CALL _strayintr(SB); BYTE $0x9B
  730. CALL _strayintr(SB); BYTE $0x9C
  731. CALL _strayintr(SB); BYTE $0x9D
  732. CALL _strayintr(SB); BYTE $0x9E
  733. CALL _strayintr(SB); BYTE $0x9F
  734. CALL _strayintr(SB); BYTE $0xA0
  735. CALL _strayintr(SB); BYTE $0xA1
  736. CALL _strayintr(SB); BYTE $0xA2
  737. CALL _strayintr(SB); BYTE $0xA3
  738. CALL _strayintr(SB); BYTE $0xA4
  739. CALL _strayintr(SB); BYTE $0xA5
  740. CALL _strayintr(SB); BYTE $0xA6
  741. CALL _strayintr(SB); BYTE $0xA7
  742. CALL _strayintr(SB); BYTE $0xA8
  743. CALL _strayintr(SB); BYTE $0xA9
  744. CALL _strayintr(SB); BYTE $0xAA
  745. CALL _strayintr(SB); BYTE $0xAB
  746. CALL _strayintr(SB); BYTE $0xAC
  747. CALL _strayintr(SB); BYTE $0xAD
  748. CALL _strayintr(SB); BYTE $0xAE
  749. CALL _strayintr(SB); BYTE $0xAF
  750. CALL _strayintr(SB); BYTE $0xB0
  751. CALL _strayintr(SB); BYTE $0xB1
  752. CALL _strayintr(SB); BYTE $0xB2
  753. CALL _strayintr(SB); BYTE $0xB3
  754. CALL _strayintr(SB); BYTE $0xB4
  755. CALL _strayintr(SB); BYTE $0xB5
  756. CALL _strayintr(SB); BYTE $0xB6
  757. CALL _strayintr(SB); BYTE $0xB7
  758. CALL _strayintr(SB); BYTE $0xB8
  759. CALL _strayintr(SB); BYTE $0xB9
  760. CALL _strayintr(SB); BYTE $0xBA
  761. CALL _strayintr(SB); BYTE $0xBB
  762. CALL _strayintr(SB); BYTE $0xBC
  763. CALL _strayintr(SB); BYTE $0xBD
  764. CALL _strayintr(SB); BYTE $0xBE
  765. CALL _strayintr(SB); BYTE $0xBF
  766. CALL _strayintr(SB); BYTE $0xC0
  767. CALL _strayintr(SB); BYTE $0xC1
  768. CALL _strayintr(SB); BYTE $0xC2
  769. CALL _strayintr(SB); BYTE $0xC3
  770. CALL _strayintr(SB); BYTE $0xC4
  771. CALL _strayintr(SB); BYTE $0xC5
  772. CALL _strayintr(SB); BYTE $0xC6
  773. CALL _strayintr(SB); BYTE $0xC7
  774. CALL _strayintr(SB); BYTE $0xC8
  775. CALL _strayintr(SB); BYTE $0xC9
  776. CALL _strayintr(SB); BYTE $0xCA
  777. CALL _strayintr(SB); BYTE $0xCB
  778. CALL _strayintr(SB); BYTE $0xCC
  779. CALL _strayintr(SB); BYTE $0xCD
  780. CALL _strayintr(SB); BYTE $0xCE
  781. CALL _strayintr(SB); BYTE $0xCF
  782. CALL _strayintr(SB); BYTE $0xD0
  783. CALL _strayintr(SB); BYTE $0xD1
  784. CALL _strayintr(SB); BYTE $0xD2
  785. CALL _strayintr(SB); BYTE $0xD3
  786. CALL _strayintr(SB); BYTE $0xD4
  787. CALL _strayintr(SB); BYTE $0xD5
  788. CALL _strayintr(SB); BYTE $0xD6
  789. CALL _strayintr(SB); BYTE $0xD7
  790. CALL _strayintr(SB); BYTE $0xD8
  791. CALL _strayintr(SB); BYTE $0xD9
  792. CALL _strayintr(SB); BYTE $0xDA
  793. CALL _strayintr(SB); BYTE $0xDB
  794. CALL _strayintr(SB); BYTE $0xDC
  795. CALL _strayintr(SB); BYTE $0xDD
  796. CALL _strayintr(SB); BYTE $0xDE
  797. CALL _strayintr(SB); BYTE $0xDF
  798. CALL _strayintr(SB); BYTE $0xE0
  799. CALL _strayintr(SB); BYTE $0xE1
  800. CALL _strayintr(SB); BYTE $0xE2
  801. CALL _strayintr(SB); BYTE $0xE3
  802. CALL _strayintr(SB); BYTE $0xE4
  803. CALL _strayintr(SB); BYTE $0xE5
  804. CALL _strayintr(SB); BYTE $0xE6
  805. CALL _strayintr(SB); BYTE $0xE7
  806. CALL _strayintr(SB); BYTE $0xE8
  807. CALL _strayintr(SB); BYTE $0xE9
  808. CALL _strayintr(SB); BYTE $0xEA
  809. CALL _strayintr(SB); BYTE $0xEB
  810. CALL _strayintr(SB); BYTE $0xEC
  811. CALL _strayintr(SB); BYTE $0xED
  812. CALL _strayintr(SB); BYTE $0xEE
  813. CALL _strayintr(SB); BYTE $0xEF
  814. CALL _strayintr(SB); BYTE $0xF0
  815. CALL _strayintr(SB); BYTE $0xF1
  816. CALL _strayintr(SB); BYTE $0xF2
  817. CALL _strayintr(SB); BYTE $0xF3
  818. CALL _strayintr(SB); BYTE $0xF4
  819. CALL _strayintr(SB); BYTE $0xF5
  820. CALL _strayintr(SB); BYTE $0xF6
  821. CALL _strayintr(SB); BYTE $0xF7
  822. CALL _strayintr(SB); BYTE $0xF8
  823. CALL _strayintr(SB); BYTE $0xF9
  824. CALL _strayintr(SB); BYTE $0xFA
  825. CALL _strayintr(SB); BYTE $0xFB
  826. CALL _strayintr(SB); BYTE $0xFC
  827. CALL _strayintr(SB); BYTE $0xFD
  828. CALL _strayintr(SB); BYTE $0xFE
  829. CALL _strayintr(SB); BYTE $0xFF