github.com/solo-io/unik@v0.0.0-20190717152701-a58d3e8e33b7/containers/compilers/includeos/cpp/patches/api/kernel/os.hpp (about) 1 // This file is a part of the IncludeOS unikernel - www.includeos.org 2 // 3 // Copyright 2015 Oslo and Akershus University College of Applied Sciences 4 // and Alfred Bratterud 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 #ifndef KERNEL_OS_HPP 19 #define KERNEL_OS_HPP 20 21 #include <string> 22 #include <sstream> 23 #include <common> 24 #include <kernel/memmap.hpp> 25 #include <hw/cpu.hpp> 26 #include <hertz> 27 #include <vector> 28 #include <kernel/rtc.hpp> 29 30 /** 31 * The entrypoint for OS services 32 * 33 * @note For device access, see Dev 34 */ 35 class OS { 36 public: 37 static bool ready_; 38 using print_func = delegate<void(const char*, size_t)>; 39 using Custom_init = delegate<void()>; 40 41 /* Get the version of the os */ 42 static std::string version() 43 { return version_field; } 44 45 /** Clock cycles since boot. */ 46 static uint64_t cycles_since_boot() { 47 return hw::CPU::rdtsc(); 48 } 49 /** micro seconds since boot */ 50 static int64_t micros_since_boot() { 51 return cycles_since_boot() / cpu_mhz_.count(); 52 } 53 54 /** Timestamp for when OS was booted */ 55 static RTC::timestamp_t boot_timestamp() 56 { return booted_at_; } 57 58 /** Uptime in whole seconds. */ 59 static RTC::timestamp_t uptime() { 60 return RTC::now() - booted_at_; 61 } 62 63 static MHz cpu_freq() noexcept 64 { return cpu_mhz_; } 65 66 /** 67 * Shutdown operating system 68 * 69 **/ 70 static void shutdown(); 71 72 /** 73 * Write data to standard out callbacks 74 */ 75 static size_t print(const char* ptr, const size_t len); 76 77 /** Start the OS. @todo Should be `init()` - and not accessible from ABI */ 78 static void start(uint32_t boot_magic, uint32_t boot_addr); 79 80 /** 81 * Halt until next interrupt. 82 * 83 * @Warning If there is no regular timer interrupt (i.e. from PIT / APIC) 84 * we'll stay asleep. 85 */ 86 static void halt(); 87 88 /** 89 * Returns true when the OS will still be running, and not shutting down. 90 */ 91 static bool is_running() { 92 return power_; 93 } 94 95 /** 96 * Add handler for standard output. 97 */ 98 static void add_stdout(print_func func); 99 100 /** Memory page helpers */ 101 static constexpr uint32_t page_size() noexcept { 102 return 4096; 103 } 104 static constexpr uint32_t page_nr_from_addr(uint32_t x) noexcept { 105 return x >> PAGE_SHIFT; 106 } 107 static constexpr uint32_t base_from_page_nr(uint32_t x) noexcept { 108 return x << PAGE_SHIFT; 109 } 110 111 /** Currently used dynamic memory, in bytes */ 112 static uintptr_t heap_usage() noexcept; 113 114 /** The maximum last address of the dynamic memory area (heap) */ 115 static uintptr_t heap_max(); 116 117 /** time spent sleeping (halt) in cycles */ 118 static uint64_t get_cycles_halt() noexcept; 119 120 /** total time spent in cycles */ 121 static uint64_t get_cycles_total() noexcept; 122 123 /** 124 * A map of memory ranges. The key is the starting address in numeric form. 125 * @note : the idea is to avoid raw pointers whenever possible 126 **/ 127 static Memory_map& memory_map() { 128 static Memory_map memmap {}; 129 return memmap; 130 } 131 132 /** 133 * Register a custom initialization function. The provided delegate is 134 * guaranteed to be called after global constructors and device initialization 135 * and before Service::start, provided that this funciton was called by a 136 * global constructor. 137 * @param delg : A delegate to be called 138 * @param name : A human readable identifier 139 **/ 140 static void register_custom_init(Custom_init delg, const char* name); 141 142 /** 143 * Block for a while, e.g. until the next round in the event loop 144 **/ 145 static void block(); 146 147 148 private: 149 150 /** Process multiboot info. Called by 'start' if multibooted **/ 151 static void multiboot(uint32_t boot_magic, uint32_t boot_addr); 152 153 static constexpr int PAGE_SHIFT = 12; 154 155 /** Indicate if the OS is running. */ 156 static bool power_; 157 158 /** The main event loop. Check interrupts, timers etc., and do callbacks. */ 159 static void event_loop(); 160 161 static MHz cpu_mhz_; 162 163 static RTC::timestamp_t booted_at_; 164 static std::string version_field; 165 166 struct Custom_init_struct { 167 Custom_init_struct(Custom_init f, const char* n) 168 : func_{f}, name_{n} 169 {} 170 171 Custom_init func_; 172 const char* name_; 173 }; 174 175 static std::vector<Custom_init_struct> custom_init_; 176 177 static uintptr_t low_memory_size_; 178 static uintptr_t high_memory_size_; 179 static uintptr_t heap_max_; 180 static const uintptr_t elf_binary_size_; 181 182 // Prohibit copy and move operations 183 OS(OS&) = delete; 184 OS(OS&&) = delete; 185 OS& operator=(OS&) = delete; 186 OS& operator=(OS&&) = delete; 187 ~OS() = delete; 188 // Prohibit construction 189 OS() = delete; 190 191 }; //< OS 192 193 #endif //< KERNEL_OS_HPP