You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			92 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C++
		
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C++
		
	
| #include "lapic.h"
 | |
| #include "lapic_registers.h"
 | |
| 
 | |
| namespace LAPIC {
 | |
| namespace Timer {
 | |
| 
 | |
| /*! \brief Timer Delivery Status */
 | |
| enum DeliveryStatus { IDLE = 0, SEND_PENDING = 1 };
 | |
| 
 | |
| /*! \brief Timer Mode */
 | |
| enum TimerMode {
 | |
|   ONE_SHOT = 0,
 | |
|   PERIODIC = 1,
 | |
|   DEADLINE = 2
 | |
|   // reserved
 | |
| };
 | |
| 
 | |
| /*! \brief Timer Mask */
 | |
| enum Mask { NOT_MASKED = 0, MASKED = 1 };
 | |
| 
 | |
| static const Register INVALID_DIV = 0xff;
 | |
| 
 | |
| /*! \brief LAPIC-Timer Control Register
 | |
|  *
 | |
|  * \see [ISDMv3 10.5.1 Local Vector Table](intel_manual_vol3.pdf#page=375)
 | |
|  */
 | |
| union ControlRegister {
 | |
|   struct {
 | |
|     uint32_t vector : 8;  ///< Vector
 | |
|     uint32_t : 4;
 | |
|     DeliveryStatus delivery_status : 1;  ///< Delivery Status (readonly)
 | |
|     uint32_t : 3;
 | |
|     Mask masked : 1;  ///< Interrupt Mask (if set, interrupt will not trigger)
 | |
|     TimerMode timer_mode : 2;  ///< Timer Mode
 | |
|     uint32_t : 13;
 | |
|   };
 | |
|   Register value;
 | |
| } __attribute__((packed));
 | |
| 
 | |
| /*! \brief LAPIC timer divider table
 | |
|  *
 | |
|  * \see [ISDMv3 10.5.4 APIC Timer](intel_manual_vol3.pdf#page=378)
 | |
|  */
 | |
| static const Register div_masks[] = {
 | |
|     0xb,  ///< divides by   1
 | |
|     0x0,  ///< divides by   2
 | |
|     0x1,  ///< divides by   4
 | |
|     0x2,  ///< divides by   8
 | |
|     0x3,  ///< divides by  16
 | |
|     0x8,  ///< divides by  32
 | |
|     0x9,  ///< divides by  64
 | |
|     0xa   ///< divides by 128
 | |
| };
 | |
| 
 | |
| /*! \brief Calculate the bit mask for the LAPIC-timer divider.
 | |
|  *  \param div Divider, must be power of two: 1, 2, 4, 8, 16, 32, 64, 128
 | |
|  *  \return Bit mask for LAPIC::setTimer() or `0xff` if `div` is invalid.
 | |
|  */
 | |
| Register getClockDiv(uint8_t div) {
 | |
|   (void)div;
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| uint32_t ticks(void) {
 | |
|   uint32_t ticks = 0;  // ticks per millisecond
 | |
|   // Calculation (Assignment 5)
 | |
|   return ticks;
 | |
| }
 | |
| 
 | |
| void set(uint32_t counter, uint8_t divide, uint8_t vector, bool periodic,
 | |
|          bool masked) {
 | |
|   (void)counter;
 | |
|   (void)divide;
 | |
|   (void)vector;
 | |
|   (void)periodic;
 | |
|   (void)masked;
 | |
| }
 | |
| 
 | |
| bool setup(uint32_t us) {
 | |
|   (void)us;
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| uint32_t interval() { return 0; }
 | |
| 
 | |
| void activate() {}
 | |
| 
 | |
| void setMasked(bool masked) { (void)masked; }
 | |
| 
 | |
| }  // namespace Timer
 | |
| }  // namespace LAPIC
 |