Kernel: Add function to retrieve boot time as timespec
This commit is contained in:
		
							parent
							
								
									868444f043
								
							
						
					
					
						commit
						17f1737c9a
					
				| 
						 | 
				
			
			@ -11,6 +11,7 @@ namespace Kernel
 | 
			
		|||
		static BAN::ErrorOr<BAN::UniqPtr<HPET>> create();
 | 
			
		||||
 | 
			
		||||
		virtual uint64_t ms_since_boot() const override;
 | 
			
		||||
		virtual timespec time_since_boot() const override;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		HPET() = default;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@ namespace Kernel
 | 
			
		|||
		static BAN::ErrorOr<BAN::UniqPtr<PIT>> create();
 | 
			
		||||
 | 
			
		||||
		virtual uint64_t ms_since_boot() const override;
 | 
			
		||||
		virtual timespec time_since_boot() const override;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		void initialize();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,16 +12,19 @@ namespace Kernel
 | 
			
		|||
	public:
 | 
			
		||||
		virtual ~Timer() {};
 | 
			
		||||
		virtual uint64_t ms_since_boot() const = 0;
 | 
			
		||||
		virtual timespec time_since_boot() const = 0;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	class TimerHandler
 | 
			
		||||
	class TimerHandler : public Timer
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		static void initialize();
 | 
			
		||||
		static TimerHandler& get();
 | 
			
		||||
		static bool is_initialized();
 | 
			
		||||
 | 
			
		||||
		uint64_t ms_since_boot() const;
 | 
			
		||||
		virtual uint64_t ms_since_boot() const override;
 | 
			
		||||
		virtual timespec time_since_boot() const override;
 | 
			
		||||
		
 | 
			
		||||
		void sleep(uint64_t) const;
 | 
			
		||||
 | 
			
		||||
		uint64_t get_unix_timestamp();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -215,7 +215,10 @@ namespace Kernel::Input
 | 
			
		|||
		event.key = key;
 | 
			
		||||
 | 
			
		||||
		if (event.pressed() && event.key == Input::Key::F11)
 | 
			
		||||
			dprintln("{} ms", TimerHandler::get().ms_since_boot());
 | 
			
		||||
		{
 | 
			
		||||
			auto time = TimerHandler::get().time_since_boot();
 | 
			
		||||
			dprintln("{}.{9} s", time.tv_sec, time.tv_nsec);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (m_event_queue.full())
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,10 @@
 | 
			
		|||
#define HPET_Tn_PER_INT_CAP	(1 << 4)
 | 
			
		||||
#define HPET_Tn_VAL_SET_CNF	(1 << 6)
 | 
			
		||||
 | 
			
		||||
#define FS_PER_MS 1'000'000'000'000
 | 
			
		||||
#define FS_PER_S	1'000'000'000'000'000
 | 
			
		||||
#define FS_PER_MS	1'000'000'000'000
 | 
			
		||||
#define FS_PER_US	1'000'000'000
 | 
			
		||||
#define FS_PER_NS	1'000'000
 | 
			
		||||
 | 
			
		||||
namespace Kernel
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -66,6 +69,18 @@ namespace Kernel
 | 
			
		|||
		m_counter_tick_period_fs = read_register(HPET_REG_CAPABILIES) >> 32;
 | 
			
		||||
 | 
			
		||||
		uint64_t ticks_per_ms = FS_PER_MS / m_counter_tick_period_fs;
 | 
			
		||||
		
 | 
			
		||||
		{
 | 
			
		||||
			const char* units[] = { "fs", "ps", "ns", "us", "ms", "s" };
 | 
			
		||||
			int index = 0;
 | 
			
		||||
			uint64_t temp = m_counter_tick_period_fs;
 | 
			
		||||
			while (temp >= 1000)
 | 
			
		||||
			{
 | 
			
		||||
				temp /= 1000;
 | 
			
		||||
				index++;
 | 
			
		||||
			}
 | 
			
		||||
			dprintln("HPET percision {} {}", temp, units[index]);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		uint64_t timer0_config = read_register(HPET_REG_TIMER_CONFIG(0));
 | 
			
		||||
		if (!(timer0_config & HPET_Tn_PER_INT_CAP))
 | 
			
		||||
| 
						 | 
				
			
			@ -100,6 +115,15 @@ namespace Kernel
 | 
			
		|||
		return read_register(HPET_REG_COUNTER) * m_counter_tick_period_fs / FS_PER_MS;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	timespec HPET::time_since_boot() const
 | 
			
		||||
	{
 | 
			
		||||
		uint64_t time_fs = read_register(HPET_REG_COUNTER) * m_counter_tick_period_fs;
 | 
			
		||||
		return timespec {
 | 
			
		||||
			.tv_sec = time_fs / FS_PER_S,
 | 
			
		||||
			.tv_nsec = (long)((time_fs % FS_PER_S) / FS_PER_NS)
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void HPET::write_register(ptrdiff_t reg, uint64_t value) const
 | 
			
		||||
	{
 | 
			
		||||
		MMIO::write64(m_mmio_base + reg, value);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,9 @@
 | 
			
		|||
#define BASE_FREQUENCY		1193182
 | 
			
		||||
#define TICKS_PER_SECOND	1000
 | 
			
		||||
 | 
			
		||||
#define MS_PER_S			1'000
 | 
			
		||||
#define NS_PER_S			1'000'000'000
 | 
			
		||||
 | 
			
		||||
namespace Kernel
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +37,7 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
	BAN::ErrorOr<BAN::UniqPtr<PIT>> PIT::create()
 | 
			
		||||
	{
 | 
			
		||||
		PIT* pit = new PIT;
 | 
			
		||||
		PIT* pit = new PIT();
 | 
			
		||||
		if (pit == nullptr)
 | 
			
		||||
			return BAN::Error::from_errno(ENOMEM);
 | 
			
		||||
		pit->initialize();
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +60,16 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
	uint64_t PIT::ms_since_boot() const
 | 
			
		||||
	{
 | 
			
		||||
		return s_system_time;
 | 
			
		||||
		return s_system_time * (MS_PER_S / TICKS_PER_SECOND);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	timespec PIT::time_since_boot() const
 | 
			
		||||
	{
 | 
			
		||||
		uint64_t ticks = s_system_time;
 | 
			
		||||
		return timespec {
 | 
			
		||||
			.tv_sec = ticks / TICKS_PER_SECOND,
 | 
			
		||||
			.tv_nsec = (long)((ticks % TICKS_PER_SECOND) * (NS_PER_S / TICKS_PER_SECOND))
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,6 +59,11 @@ namespace Kernel
 | 
			
		|||
		return m_timer->ms_since_boot();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	timespec TimerHandler::time_since_boot() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_timer->time_since_boot();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void TimerHandler::sleep(uint64_t ms) const
 | 
			
		||||
	{
 | 
			
		||||
		if (ms == 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue