- Timestamp:
- Aug 3, 2023 1:15:55 AM (19 months ago)
- svn:sync-xref-src-repo-rev:
- 158666
- Location:
- trunk/src/VBox/ValidationKit/bootsectors
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/Makefile.kmk
r100733 r100782 426 426 bs3kit/bs3-first-rm.asm \ 427 427 bs3-timers-1.c \ 428 bs3-timers-1-x0.c 428 bs3-timers-1-x0.c \ 429 bs3-timers-1-asm.asm 429 430 430 431 # -
trunk/src/VBox/ValidationKit/bootsectors/bs3-timers-1-x0.c
r98103 r100782 45 45 46 46 47 static uint8_t bs3Timers1_Pit(uint8_t bMode, uint16_t uHz, uint32_t cNsMaxDiviation) 47 /********************************************************************************************************************************* 48 * Structures and Typedefs * 49 *********************************************************************************************************************************/ 50 typedef enum BS3TIMERSIRQLOOP 51 { 52 BS3TIMERSIRQLOOP_INVALID = 0, 53 BS3TIMERSIRQLOOP_SIMPLE, 54 BS3TIMERSIRQLOOP_STI_HLT_CLI, 55 BS3TIMERSIRQLOOP_STI_STI_CLI, 56 BS3TIMERSIRQLOOP_POPF_CLI, 57 BS3TIMERSIRQLOOP_END 58 } BS3TIMERSIRQLOOP; 59 60 61 typedef enum BS3TIMERSNOIRQLOOP 62 { 63 BS3TIMERSNOIRQLOOP_INVALID = 0, 64 BS3TIMERSNOIRQLOOP_SIMPLE, 65 BS3TIMERSNOIRQLOOP_STI_CLI, 66 BS3TIMERSNOIRQLOOP_END 67 } BS3TIMERSNOIRQLOOP; 68 69 70 /********************************************************************************************************************************* 71 * External Assembly Functions * 72 *********************************************************************************************************************************/ 73 extern FNBS3NEAR bs3Timers1StiHltCli; 74 extern FNBS3NEAR bs3Timers1StiHltCli_IrqPc; 75 extern FNBS3NEAR bs3Timers1StiStiCli; 76 extern FNBS3NEAR bs3Timers1StiStiCli_IrqPc; 77 extern FNBS3NEAR bs3Timers1PopfCli; 78 extern FNBS3NEAR bs3Timers1PopfCli_IrqPc; 79 80 extern FNBS3NEAR bs3Timers1StiCli; 81 82 83 84 static uint8_t bs3Timers1_Pit(uint8_t bMode, uint16_t uHz, uint32_t cNsMaxDiviation, BS3TIMERSIRQLOOP enmIrqLoop) 48 85 { 49 86 uint32_t const cTargetTicks = uHz * 3; … … 53 90 uint64_t cNsDeltaAbs; 54 91 92 ASMIntEnable(); 93 ASMNopPause(); 94 ASMIntDisable(); 95 96 97 ASMIntDisable(); /* paranoia */ 55 98 Bs3PitSetupAndEnablePeriodTimer(uHz); 56 99 cNsElapsed = Bs3TestNow(); 57 ASMIntEnable();58 100 uActualHz = g_cBs3PitIntervalHz; 59 101 60 while (g_cBs3PitTicks < cTargetTicks) 61 ASMHalt(); 102 switch (enmIrqLoop) 103 { 104 default: 105 case BS3TIMERSIRQLOOP_SIMPLE: 106 ASMIntEnable(); 107 while (g_cBs3PitTicks < cTargetTicks) 108 ASMHalt(); 109 break; 110 111 /* This variant enabls interrupt like this: sti; hlt; cli */ 112 case BS3TIMERSIRQLOOP_STI_HLT_CLI: 113 while (g_cBs3PitTicks < cTargetTicks) 114 { 115 uint32_t const uIrqPc = g_Bs3PitIrqRip.u32; 116 if (uIrqPc == (uint16_t)&bs3Timers1StiHltCli_IrqPc || uIrqPc == 0) 117 bs3Timers1StiHltCli(); 118 else 119 { 120 Bs3TestFailedF("IrqPC = %#RX32, expected %#RX16!\n", uIrqPc, (uint16_t)&bs3Timers1StiHltCli_IrqPc); 121 break; 122 } 123 } 124 break; 125 126 /* This variant enabls interrupt like this: sti; sti; cli */ 127 case BS3TIMERSIRQLOOP_STI_STI_CLI: 128 while (g_cBs3PitTicks < cTargetTicks) 129 { 130 uint32_t const uIrqPc = g_Bs3PitIrqRip.u32; 131 if (uIrqPc == (uint16_t)&bs3Timers1StiStiCli_IrqPc || uIrqPc == 0) 132 bs3Timers1StiStiCli(); 133 else 134 { 135 Bs3TestFailedF("IrqPC = %#RX32, expected %#RX16!\n", uIrqPc, (uint16_t)&bs3Timers1StiStiCli_IrqPc); 136 break; 137 } 138 } 139 break; 140 141 /* This variant enabls interrupt like this: enabling-if-popf; cli */ 142 case BS3TIMERSIRQLOOP_POPF_CLI: 143 while (g_cBs3PitTicks < cTargetTicks) 144 { 145 uint32_t const uIrqPc = g_Bs3PitIrqRip.u32; 146 if (uIrqPc == (uint16_t)&bs3Timers1PopfCli_IrqPc || uIrqPc == 0) 147 bs3Timers1PopfCli(); 148 else 149 { 150 Bs3TestFailedF("IrqPC = %#RX32, expected %#RX16!\n", uIrqPc, (uint16_t)&bs3Timers1PopfCli_IrqPc); 151 break; 152 } 153 } 154 break; 155 } 62 156 63 157 Bs3PitDisable(); … … 73 167 Bs3TestFailedF("delta %c%RU64 ns (%RI32 ms), max %RU32 ns", cNsDelta < 0 ? '-' : '+', cNsDeltaAbs, 74 168 (int32_t)((uint64_t)cNsDelta / RT_NS_1MS), cNsMaxDiviation); 169 else if (g_Bs3PitIrqRip.u32 == 0) 170 Bs3TestFailedF("g_Bs3PitIrqRip.u32 is zero!\n"); 75 171 76 172 return 0; … … 80 176 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3Timers1_Pit_100Hz)(uint8_t bMode) 81 177 { 82 return bs3Timers1_Pit(bMode, 100, RT_NS_10MS );178 return bs3Timers1_Pit(bMode, 100, RT_NS_10MS, BS3TIMERSIRQLOOP_SIMPLE); 83 179 } 84 180 … … 86 182 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3Timers1_Pit_1000Hz)(uint8_t bMode) 87 183 { 88 return bs3Timers1_Pit(bMode, 1000, RT_NS_10MS );184 return bs3Timers1_Pit(bMode, 1000, RT_NS_10MS, BS3TIMERSIRQLOOP_SIMPLE); 89 185 } 90 186 … … 92 188 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3Timers1_Pit_2000Hz)(uint8_t bMode) 93 189 { 94 return bs3Timers1_Pit(bMode, 2000, RT_NS_10MS*2 );190 return bs3Timers1_Pit(bMode, 2000, RT_NS_10MS*2, BS3TIMERSIRQLOOP_SIMPLE); 95 191 } 96 192 … … 98 194 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3Timers1_Pit_4000Hz)(uint8_t bMode) 99 195 { 100 return bs3Timers1_Pit(bMode, 4000, RT_NS_10MS*4); 101 } 102 196 return bs3Timers1_Pit(bMode, 4000, RT_NS_10MS*4, BS3TIMERSIRQLOOP_SIMPLE); 197 } 198 199 200 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3Timers1_Pit_100Hz_wait1)(uint8_t bMode) 201 { 202 return bs3Timers1_Pit(bMode, 100, RT_NS_10MS, BS3TIMERSIRQLOOP_STI_HLT_CLI); 203 } 204 205 206 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3Timers1_Pit_100Hz_wait2)(uint8_t bMode) 207 { 208 return bs3Timers1_Pit(bMode, 100, RT_NS_10MS, BS3TIMERSIRQLOOP_STI_STI_CLI); 209 } 210 211 212 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3Timers1_Pit_100Hz_wait3)(uint8_t bMode) 213 { 214 return bs3Timers1_Pit(bMode, 100, RT_NS_10MS, BS3TIMERSIRQLOOP_POPF_CLI); 215 } 216 217 218 /** 219 * Negative test loop, i.e. no interrupts delivered. 220 * 221 * This is for testing interrupt disabling and inhibition 222 */ 223 static uint8_t bs3Timers1_PitNegative(uint8_t bMode, uint16_t uHz, BS3TIMERSNOIRQLOOP enmLoop) 224 { 225 uint64_t uNsStart; 226 227 ASMIntDisable(); /* paranoia */ 228 Bs3PitSetupAndEnablePeriodTimer(uHz); 229 uNsStart = Bs3TestNow(); 230 231 switch (enmLoop) 232 { 233 default: 234 case BS3TIMERSNOIRQLOOP_SIMPLE: 235 while (Bs3TestNow() - uNsStart < RT_NS_1SEC * 2) 236 ASMNopPause(); 237 break; 238 239 case BS3TIMERSNOIRQLOOP_STI_CLI: 240 while (Bs3TestNow() - uNsStart < RT_NS_1SEC * 2) 241 bs3Timers1StiCli(); 242 break; 243 } 244 245 Bs3PitDisable(); 246 247 if (g_cBs3PitTicks > 0) 248 Bs3TestFailedF("g_cBs3PitTicks=%RU32, expected zero!\n", g_cBs3PitTicks); 249 250 ASMIntEnable(); 251 ASMNopPause(); 252 ASMIntDisable(); 253 254 return 0; 255 } 256 257 258 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3Timers1_Pit_100Hz_negative1)(uint8_t bMode) 259 { 260 return bs3Timers1_PitNegative(bMode, 100, BS3TIMERSNOIRQLOOP_SIMPLE); 261 } 262 263 264 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3Timers1_Pit_100Hz_negative2)(uint8_t bMode) 265 { 266 return bs3Timers1_PitNegative(bMode, 100, BS3TIMERSNOIRQLOOP_STI_CLI); 267 } 268 -
trunk/src/VBox/ValidationKit/bootsectors/bs3-timers-1.c
r98103 r100782 50 50 FNBS3TESTDOMODE bs3Timers1_Pit_2000Hz_f16; 51 51 FNBS3TESTDOMODE bs3Timers1_Pit_4000Hz_f16; 52 FNBS3TESTDOMODE bs3Timers1_Pit_100Hz_wait1_f16; 53 FNBS3TESTDOMODE bs3Timers1_Pit_100Hz_wait2_f16; 54 FNBS3TESTDOMODE bs3Timers1_Pit_100Hz_wait3_f16; 55 FNBS3TESTDOMODE bs3Timers1_Pit_100Hz_negative1_f16; 56 FNBS3TESTDOMODE bs3Timers1_Pit_100Hz_negative2_f16; 52 57 53 58 … … 57 62 static const BS3TESTMODEBYONEENTRY g_aModeByOneTests[] = 58 63 { 59 { "pit-100Hz", bs3Timers1_Pit_100Hz_f16, BS3TESTMODEBYONEENTRY_F_MINIMAL }, 60 { "pit-1000Hz", bs3Timers1_Pit_1000Hz_f16, BS3TESTMODEBYONEENTRY_F_MINIMAL }, 61 { "pit-2000Hz", bs3Timers1_Pit_2000Hz_f16, BS3TESTMODEBYONEENTRY_F_MINIMAL }, 62 { "pit-4000Hz", bs3Timers1_Pit_4000Hz_f16, BS3TESTMODEBYONEENTRY_F_MINIMAL }, 64 #if 0 65 { "pit-100Hz", bs3Timers1_Pit_100Hz_f16, BS3TESTMODEBYONEENTRY_F_MINIMAL }, 66 { "pit-1000Hz", bs3Timers1_Pit_1000Hz_f16, BS3TESTMODEBYONEENTRY_F_MINIMAL }, 67 { "pit-2000Hz", bs3Timers1_Pit_2000Hz_f16, BS3TESTMODEBYONEENTRY_F_MINIMAL }, 68 { "pit-4000Hz", bs3Timers1_Pit_4000Hz_f16, BS3TESTMODEBYONEENTRY_F_MINIMAL }, 69 { "pit-100Hz-wait1", bs3Timers1_Pit_100Hz_wait1_f16, BS3TESTMODEBYONEENTRY_F_MINIMAL }, 70 #endif 71 { "pit-100Hz-wait2", bs3Timers1_Pit_100Hz_wait2_f16, BS3TESTMODEBYONEENTRY_F_MINIMAL }, 72 { "pit-100Hz-wait3", bs3Timers1_Pit_100Hz_wait3_f16, BS3TESTMODEBYONEENTRY_F_MINIMAL }, 73 { "pit-100Hz-neg1", bs3Timers1_Pit_100Hz_negative1_f16, BS3TESTMODEBYONEENTRY_F_MINIMAL }, 74 { "pit-100Hz-neg2", bs3Timers1_Pit_100Hz_negative2_f16, BS3TESTMODEBYONEENTRY_F_MINIMAL }, 63 75 }; 64 76 -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PitIrqHandler.c
r98103 r100782 47 47 *********************************************************************************************************************************/ 48 48 #if ARCH_BITS == 16 49 /** The RIP/EIP value of where the PIT IRQ handle will return to. */ 50 BS3REG volatile g_Bs3PitIrqRip; 49 51 /** Nano seconds (approx) since last the PIT timer was started. */ 50 52 uint64_t volatile g_cBs3PitNs = 0; … … 70 72 g_cBs3PitNs += g_cBs3PitIntervalNs; 71 73 g_cBs3PitTicks++; 74 g_Bs3PitIrqRip.u = pTrapFrame->Ctx.rip.u; 72 75 } 73 76 NOREF(pTrapFrame); -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-pit.c
r98103 r100782 75 75 76 76 /* 77 * Reset the counters .77 * Reset the counters and IRQ PC. 78 78 */ 79 79 g_cBs3PitNs = 0; 80 80 g_cBs3PitMs = 0; 81 81 g_cBs3PitTicks = 0; 82 g_Bs3PitIrqRip.u = 0; 82 83 83 84 /* -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h
r98103 r100782 2516 2516 BS3_CMN_PROTO_STUB(void BS3_FAR *, Bs3PagingSetupCanonicalTraps,(void)); 2517 2517 2518 /**2519 * Waits for the keyboard controller to become ready.2520 */2521 BS3_CMN_PROTO_NOSB(void, Bs3KbdWait,(void));2522 2523 /**2524 * Sends a read command to the keyboard controller and gets the result.2525 *2526 * The caller is responsible for making sure the keyboard controller is ready2527 * for a command (call #Bs3KbdWait if unsure).2528 *2529 * @returns The value read is returned (in al).2530 * @param bCmd The read command.2531 */2532 BS3_CMN_PROTO_NOSB(uint8_t, Bs3KbdRead,(uint8_t bCmd));2533 2534 /**2535 * Sends a write command to the keyboard controller and then sends the data.2536 *2537 * The caller is responsible for making sure the keyboard controller is ready2538 * for a command (call #Bs3KbdWait if unsure).2539 *2540 * @param bCmd The write command.2541 * @param bData The data to write.2542 */2543 BS3_CMN_PROTO_NOSB(void, Bs3KbdWrite,(uint8_t bCmd, uint8_t bData));2544 2545 2546 /**2547 * Configures the PIC, once only.2548 *2549 * Subsequent calls to this function will not do anything.2550 *2551 * The PIC will be programmed to use IDT/IVT vectors 0x70 thru 0x7f, auto2552 * end-of-interrupt, and all IRQs masked. The individual PIC users will have to2553 * use #Bs3PicUpdateMask unmask their IRQ once they've got all the handlers2554 * installed.2555 *2556 * @param fForcedReInit Force a reinitialization.2557 */2558 BS3_CMN_PROTO_STUB(void, Bs3PicSetup,(bool fForcedReInit));2559 2560 /**2561 * Updates the PIC masks.2562 *2563 * @returns The new mask - master in low, slave in high byte.2564 * @param fAndMask Things to keep as-is. Master in low, slave in high byte.2565 * @param fOrMask Things to start masking. Ditto wrt bytes.2566 */2567 BS3_CMN_PROTO_STUB(uint16_t, Bs3PicUpdateMask,(uint16_t fAndMask, uint16_t fOrMask));2568 2569 /**2570 * Disables all IRQs on the PIC.2571 */2572 BS3_CMN_PROTO_STUB(void, Bs3PicMaskAll,(void));2573 2574 2575 /**2576 * Sets up the PIT for periodic callback.2577 *2578 * @param cHzDesired The desired Hz. Zero means max interval length2579 * (18.2Hz). Plase check the various PIT globals for2580 * the actual interval length.2581 */2582 BS3_CMN_PROTO_STUB(void, Bs3PitSetupAndEnablePeriodTimer,(uint16_t cHzDesired));2583 2584 /**2585 * Disables the PIT if active.2586 */2587 BS3_CMN_PROTO_STUB(void, Bs3PitDisable,(void));2588 2589 /** Nanoseconds (approx) since last the PIT timer was started. */2590 extern uint64_t volatile g_cBs3PitNs;2591 /** Milliseconds seconds (very approx) since last the PIT timer was started. */2592 extern uint64_t volatile g_cBs3PitMs;2593 /** Number of ticks since last the PIT timer was started. */2594 extern uint32_t volatile g_cBs3PitTicks;2595 /** The current interval in nanoseconds.2596 * This is 0 if not yet started (cleared by Bs3PitDisable). */2597 extern uint32_t g_cBs3PitIntervalNs;2598 /** The current interval in milliseconds (approximately).2599 * This is 0 if not yet started (cleared by Bs3PitDisable). */2600 extern uint16_t g_cBs3PitIntervalMs;2601 /** The current PIT frequency (approximately).2602 * 0 if not yet started (cleared by Bs3PitDisable; used for checking the2603 * state internally). */2604 extern uint16_t volatile g_cBs3PitIntervalHz;2605 2606 2518 2607 2519 /** … … 4504 4416 4505 4417 4418 /** @defgroup grp_bs3kit_kbd Keyboard 4419 * @{ 4420 */ 4421 4422 /** 4423 * Waits for the keyboard controller to become ready. 4424 */ 4425 BS3_CMN_PROTO_NOSB(void, Bs3KbdWait,(void)); 4426 4427 /** 4428 * Sends a read command to the keyboard controller and gets the result. 4429 * 4430 * The caller is responsible for making sure the keyboard controller is ready 4431 * for a command (call #Bs3KbdWait if unsure). 4432 * 4433 * @returns The value read is returned (in al). 4434 * @param bCmd The read command. 4435 */ 4436 BS3_CMN_PROTO_NOSB(uint8_t, Bs3KbdRead,(uint8_t bCmd)); 4437 4438 /** 4439 * Sends a write command to the keyboard controller and then sends the data. 4440 * 4441 * The caller is responsible for making sure the keyboard controller is ready 4442 * for a command (call #Bs3KbdWait if unsure). 4443 * 4444 * @param bCmd The write command. 4445 * @param bData The data to write. 4446 */ 4447 BS3_CMN_PROTO_NOSB(void, Bs3KbdWrite,(uint8_t bCmd, uint8_t bData)); 4448 4449 /** @} */ 4450 4451 4452 /** @defgroup grp_bs3kit_pic PIC 4453 * @{ 4454 */ 4455 4456 /** 4457 * Configures the PIC, once only. 4458 * 4459 * Subsequent calls to this function will not do anything. 4460 * 4461 * The PIC will be programmed to use IDT/IVT vectors 0x70 thru 0x7f, auto 4462 * end-of-interrupt, and all IRQs masked. The individual PIC users will have to 4463 * use #Bs3PicUpdateMask unmask their IRQ once they've got all the handlers 4464 * installed. 4465 * 4466 * @param fForcedReInit Force a reinitialization. 4467 */ 4468 BS3_CMN_PROTO_STUB(void, Bs3PicSetup,(bool fForcedReInit)); 4469 4470 /** 4471 * Updates the PIC masks. 4472 * 4473 * @returns The new mask - master in low, slave in high byte. 4474 * @param fAndMask Things to keep as-is. Master in low, slave in high byte. 4475 * @param fOrMask Things to start masking. Ditto wrt bytes. 4476 */ 4477 BS3_CMN_PROTO_STUB(uint16_t, Bs3PicUpdateMask,(uint16_t fAndMask, uint16_t fOrMask)); 4478 4479 /** 4480 * Disables all IRQs on the PIC. 4481 */ 4482 BS3_CMN_PROTO_STUB(void, Bs3PicMaskAll,(void)); 4483 4484 /** @} */ 4485 4486 4487 /** @defgroup grp_bs3kit_pit PIT 4488 * @{ 4489 */ 4490 4491 /** 4492 * Sets up the PIT for periodic callback. 4493 * 4494 * @param cHzDesired The desired Hz. Zero means max interval length 4495 * (18.2Hz). Plase check the various PIT globals for 4496 * the actual interval length. 4497 */ 4498 BS3_CMN_PROTO_STUB(void, Bs3PitSetupAndEnablePeriodTimer,(uint16_t cHzDesired)); 4499 4500 /** 4501 * Disables the PIT if active. 4502 */ 4503 BS3_CMN_PROTO_STUB(void, Bs3PitDisable,(void)); 4504 4505 /** The RIP/EIP value of where the PIT IRQ handle will return to. */ 4506 extern BS3REG volatile g_Bs3PitIrqRip; 4507 /** Nanoseconds (approx) since last the PIT timer was started. */ 4508 extern uint64_t volatile g_cBs3PitNs; 4509 /** Milliseconds seconds (very approx) since last the PIT timer was started. */ 4510 extern uint64_t volatile g_cBs3PitMs; 4511 /** Number of ticks since last the PIT timer was started. */ 4512 extern uint32_t volatile g_cBs3PitTicks; 4513 /** The current interval in nanoseconds. 4514 * This is 0 if not yet started (cleared by Bs3PitDisable). */ 4515 extern uint32_t g_cBs3PitIntervalNs; 4516 /** The current interval in milliseconds (approximately). 4517 * This is 0 if not yet started (cleared by Bs3PitDisable). */ 4518 extern uint16_t g_cBs3PitIntervalMs; 4519 /** The current PIT frequency (approximately). 4520 * 0 if not yet started (cleared by Bs3PitDisable; used for checking the 4521 * state internally). */ 4522 extern uint16_t volatile g_cBs3PitIntervalHz; 4523 4524 /** @} */ 4525 4526 4506 4527 /** @} */ 4507 4528
Note:
See TracChangeset
for help on using the changeset viewer.