├── CHANGELOG ├── LICENSE ├── README.md ├── build └── Makefile ├── doc └── specification.pdf ├── include ├── acpi.hpp ├── acpi_dmar.hpp ├── acpi_fadt.hpp ├── acpi_gas.hpp ├── acpi_hpet.hpp ├── acpi_madt.hpp ├── acpi_mcfg.hpp ├── acpi_rsdp.hpp ├── acpi_rsdt.hpp ├── acpi_table.hpp ├── arch.hpp ├── assert.hpp ├── atomic.hpp ├── avl.hpp ├── barrier.hpp ├── bits.hpp ├── buddy.hpp ├── capability.hpp ├── cmdline.hpp ├── compiler.hpp ├── config.hpp ├── console.hpp ├── console_serial.hpp ├── console_vga.hpp ├── counter.hpp ├── cpu.hpp ├── cpuset.hpp ├── crd.hpp ├── descriptor.hpp ├── dmar.hpp ├── dpt.hpp ├── ec.hpp ├── elf.hpp ├── ept.hpp ├── extern.hpp ├── fpu.hpp ├── gdt.hpp ├── gsi.hpp ├── hazards.hpp ├── hip.hpp ├── hpet.hpp ├── hpt.hpp ├── idt.hpp ├── initprio.hpp ├── io.hpp ├── ioapic.hpp ├── keyb.hpp ├── kobject.hpp ├── lapic.hpp ├── list.hpp ├── lock_guard.hpp ├── mca.hpp ├── mdb.hpp ├── memory.hpp ├── msr.hpp ├── mtd.hpp ├── mtrr.hpp ├── multiboot.hpp ├── pci.hpp ├── pd.hpp ├── pt.hpp ├── pte.hpp ├── qpd.hpp ├── queue.hpp ├── rcu.hpp ├── refptr.hpp ├── regs.hpp ├── sc.hpp ├── selectors.hpp ├── slab.hpp ├── sm.hpp ├── space.hpp ├── space_mem.hpp ├── space_obj.hpp ├── space_pio.hpp ├── spinlock.hpp ├── stdio.hpp ├── string.hpp ├── svm.hpp ├── syscall.hpp ├── tss.hpp ├── types.hpp ├── user.hpp ├── utcb.hpp ├── util.hpp ├── vectors.hpp ├── vmx.hpp ├── vpid.hpp ├── vtlb.hpp └── x86.hpp └── src ├── acpi.cpp ├── acpi_dmar.cpp ├── acpi_fadt.cpp ├── acpi_hpet.cpp ├── acpi_madt.cpp ├── acpi_mcfg.cpp ├── acpi_rsdp.cpp ├── acpi_rsdt.cpp ├── acpi_table.cpp ├── avl.cpp ├── bootstrap.cpp ├── buddy.cpp ├── cmdline.cpp ├── console.cpp ├── console_serial.cpp ├── console_vga.cpp ├── counter.cpp ├── cpu.cpp ├── dmar.cpp ├── ec.cpp ├── ec_exc.cpp ├── ec_svm.cpp ├── ec_vmx.cpp ├── entry.S ├── fpu.cpp ├── gdt.cpp ├── gsi.cpp ├── hip.cpp ├── hpet.cpp ├── hpt.cpp ├── hypervisor.ld ├── idt.cpp ├── init.cpp ├── ioapic.cpp ├── keyb.cpp ├── lapic.cpp ├── mca.cpp ├── mdb.cpp ├── memory.cpp ├── mtrr.cpp ├── pci.cpp ├── pd.cpp ├── pt.cpp ├── pte.cpp ├── rcu.cpp ├── regs.cpp ├── sc.cpp ├── slab.cpp ├── sm.cpp ├── space_mem.cpp ├── space_obj.cpp ├── space_pio.cpp ├── start.S ├── string.cpp ├── svm.cpp ├── syscall.cpp ├── tss.cpp ├── utcb.cpp ├── vmx.cpp └── vtlb.cpp /CHANGELOG: -------------------------------------------------------------------------------- 1 | 0.4 2 | --- 3 | * IOMMU fault fixes. 4 | * Secure device and GSI assignment using capabilities. 5 | * BSP indicator passed to bootstrap EC and removed from HIP. 6 | * Added revoke filtering. 7 | * Root capability of newly created objects now stored in creator PD. 8 | * Added SC control hypercall. 9 | * Added SC execution time statistics. 10 | * Added capability permissions for EC bind and EC/SC control 11 | * Improved RCU grace period handling. 12 | * Bug fixes. 13 | 14 | 0.3 15 | --- 16 | * ACPI-based CPU numbering. 17 | * Additional capability permissions. 18 | * Capability translation. 19 | * TSC offsetting. 20 | * vTLB support for SVM (enables VM support under QEMU). 21 | * Improved vTLB fills. 22 | * Improved initialization, paging, and RCU. 23 | * Bug fixes. 24 | 25 | 0.2 26 | --- 27 | * Number of supported CPUs increased to 32. 28 | * Number of supported GSIs increased to 128. 29 | * Removed 8259 PIC mode and made IOAPIC a requirement. 30 | * Root PD no longer holds GSI capabilities at bootup. 31 | * Incoming portal id no longer stored in UTCB. 32 | * New mapping database and lookup hypercall. 33 | * Selective memory delegation (host/guest/IOMMU). 34 | * Revocation of platform resources (mem/IO). 35 | * PCI topology discovery. 36 | * VT-d interrupt remapping. 37 | * Direct assignment of PCI devices and GSIs to PDs. 38 | * VMX unrestricted guest. 39 | * vTLB page splintering. 40 | * Bug fixes. 41 | 42 | 0.1 43 | --- 44 | * Initial release 45 | -------------------------------------------------------------------------------- /doc/specification.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUD-OS/NOVA/c67b7cb61618cf7f23151a45069cfe34bccd012f/doc/specification.pdf -------------------------------------------------------------------------------- /include/acpi_dmar.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "acpi_table.hpp" 22 | 23 | /* 24 | * Device Scope Structure 25 | */ 26 | class Acpi_scope 27 | { 28 | public: 29 | uint8 type; 30 | uint8 length; 31 | uint16 reserved; 32 | uint8 id, b, d, f; 33 | 34 | ALWAYS_INLINE 35 | inline unsigned rid() const { return b << 8 | d << 3 | f; } 36 | }; 37 | 38 | /* 39 | * Remapping Structure 40 | */ 41 | class Acpi_remap 42 | { 43 | public: 44 | uint16 type; 45 | uint16 length; 46 | 47 | enum Type 48 | { 49 | DMAR = 0, 50 | RMRR = 1, 51 | ATSR = 2 52 | }; 53 | }; 54 | 55 | /* 56 | * DMA Remapping Hardware Unit Definition Structure 57 | */ 58 | class Acpi_dmar : public Acpi_remap 59 | { 60 | public: 61 | uint8 flags; 62 | uint8 reserved; 63 | uint16 segment; 64 | uint64 phys; 65 | Acpi_scope scope[]; 66 | 67 | INIT 68 | void parse() const; 69 | }; 70 | 71 | /* 72 | * Reserved Memory Region Reporting Structure 73 | */ 74 | class Acpi_rmrr : public Acpi_remap 75 | { 76 | public: 77 | uint16 reserved; 78 | uint16 segment; 79 | uint64 base; 80 | uint64 limit; 81 | Acpi_scope scope[]; 82 | 83 | INIT 84 | void parse() const; 85 | }; 86 | 87 | /* 88 | * Root Port ATS Capability Reporting Structure 89 | */ 90 | class Acpi_atsr : public Acpi_remap 91 | { 92 | public: 93 | uint8 flags; 94 | uint8 reserved; 95 | uint16 segment; 96 | Acpi_scope scope[]; 97 | 98 | INIT 99 | void parse() const; 100 | }; 101 | 102 | /* 103 | * DMA Remapping Reporting Structure 104 | */ 105 | class Acpi_table_dmar : public Acpi_table 106 | { 107 | public: 108 | uint8 haw; 109 | uint8 flags; 110 | uint8 reserved[10]; 111 | Acpi_remap remap[]; 112 | 113 | INIT 114 | void parse() const; 115 | }; 116 | -------------------------------------------------------------------------------- /include/acpi_gas.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "compiler.hpp" 24 | #include "types.hpp" 25 | 26 | #pragma pack(1) 27 | 28 | /* 29 | * Generic Address Structure (5.2.3.1) 30 | */ 31 | class Acpi_gas 32 | { 33 | public: 34 | uint8 asid; // ASID 35 | uint8 bits; // Register Size (bits) 36 | uint8 offset; // Register Offset 37 | uint8 access; // Access Size 38 | uint64 addr; // Register Address 39 | 40 | enum Asid 41 | { 42 | MEMORY = 0x0, 43 | IO = 0x1, 44 | PCI_CONFIG = 0x2, 45 | EC = 0x3, 46 | SMBUS = 0x4, 47 | FIXED = 0x7f 48 | }; 49 | 50 | void init (Asid reg_asid, unsigned reg_bytes, uint64 reg_addr) 51 | { 52 | asid = reg_asid; 53 | bits = static_cast(reg_bytes * 8); 54 | addr = reg_addr; 55 | } 56 | }; 57 | 58 | #pragma pack() 59 | -------------------------------------------------------------------------------- /include/acpi_hpet.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 5 | * 6 | * This file is part of the NOVA microhypervisor. 7 | * 8 | * NOVA is free software: you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License version 2 as 10 | * published by the Free Software Foundation. 11 | * 12 | * NOVA is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License version 2 for more details. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "acpi_gas.hpp" 21 | #include "acpi_table.hpp" 22 | 23 | #pragma pack(1) 24 | 25 | class Acpi_table_hpet : public Acpi_table 26 | { 27 | public: 28 | uint32 cap; 29 | Acpi_gas hpet; 30 | uint8 id; 31 | uint16 tick; 32 | 33 | INIT 34 | void parse() const; 35 | }; 36 | 37 | #pragma pack() 38 | -------------------------------------------------------------------------------- /include/acpi_madt.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "acpi_table.hpp" 22 | 23 | #pragma pack(1) 24 | 25 | /* 26 | * ACPI INTI Flags (5.2.11.8) 27 | */ 28 | class Acpi_inti 29 | { 30 | public: 31 | uint16 pol : 2, 32 | trg : 2, 33 | : 12; 34 | 35 | enum Polarity 36 | { 37 | POL_CONFORMING = 0, 38 | POL_HIGH = 1, 39 | POL_LOW = 3, 40 | }; 41 | 42 | enum Trigger 43 | { 44 | TRG_CONFORMING = 0, 45 | TRG_EDGE = 1, 46 | TRG_LEVEL = 3 47 | }; 48 | }; 49 | 50 | /* 51 | * APIC Structure (5.2.11.4) 52 | */ 53 | class Acpi_apic 54 | { 55 | public: 56 | uint8 type; 57 | uint8 length; 58 | 59 | enum Type 60 | { 61 | LAPIC = 0, 62 | IOAPIC = 1, 63 | INTR = 2, 64 | }; 65 | }; 66 | 67 | /* 68 | * Processor Local APIC (5.2.11.5) 69 | */ 70 | class Acpi_lapic : public Acpi_apic 71 | { 72 | public: 73 | uint8 cpu; 74 | uint8 id; 75 | uint32 flags; 76 | }; 77 | 78 | /* 79 | * I/O APIC (5.2.11.6) 80 | */ 81 | class Acpi_ioapic : public Acpi_apic 82 | { 83 | public: 84 | uint8 id; 85 | uint8 zero; 86 | uint32 phys; 87 | uint32 gsi; 88 | }; 89 | 90 | /* 91 | * Interrupt Source Override (5.2.11.8) 92 | */ 93 | class Acpi_intr : public Acpi_apic 94 | { 95 | public: 96 | uint8 bus; 97 | uint8 irq; 98 | uint32 gsi; 99 | Acpi_inti flags; 100 | }; 101 | 102 | /* 103 | * Multiple APIC Description Table 104 | */ 105 | class Acpi_table_madt : public Acpi_table 106 | { 107 | private: 108 | INIT 109 | static void parse_lapic (Acpi_apic const *); 110 | 111 | INIT 112 | static void parse_ioapic (Acpi_apic const *); 113 | 114 | INIT 115 | void parse_entry (Acpi_apic::Type, void (*)(Acpi_apic const *)) const; 116 | 117 | public: 118 | uint32 apic_addr; 119 | uint32 flags; 120 | Acpi_apic apic[]; 121 | 122 | static bool sci_overridden; 123 | 124 | INIT 125 | void parse() const; 126 | 127 | INIT 128 | static void parse_intr (Acpi_apic const *); 129 | }; 130 | 131 | #pragma pack() 132 | -------------------------------------------------------------------------------- /include/acpi_mcfg.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "acpi_table.hpp" 22 | 23 | #pragma pack(1) 24 | 25 | class Acpi_mcfg 26 | { 27 | public: 28 | uint64 addr; 29 | uint16 seg; 30 | uint8 bus_s; 31 | uint8 bus_e; 32 | uint32 reserved; 33 | }; 34 | 35 | class Acpi_table_mcfg : public Acpi_table 36 | { 37 | public: 38 | uint64 reserved; 39 | Acpi_mcfg mcfg[]; 40 | 41 | INIT 42 | void parse() const; 43 | }; 44 | 45 | #pragma pack() 46 | -------------------------------------------------------------------------------- /include/acpi_rsdp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | 23 | #define SIG(A,B,C,D) (A + (B << 8) + (C << 16) + (D << 24)) 24 | 25 | /* 26 | * Root System Description Pointer (5.2.5) 27 | */ 28 | class Acpi_rsdp 29 | { 30 | private: 31 | uint32 signature[2]; 32 | uint8 checksum; 33 | char oem_id[6]; 34 | uint8 revision; 35 | uint32 rsdt_addr; 36 | uint32 length; 37 | uint64 xsdt_addr; 38 | uint8 extended_checksum; 39 | 40 | ALWAYS_INLINE 41 | bool good_signature() const 42 | { 43 | return signature[0] == SIG ('R','S','D',' ') && 44 | signature[1] == SIG ('P','T','R',' '); 45 | } 46 | 47 | ALWAYS_INLINE 48 | bool good_checksum (unsigned len = 20) const 49 | { 50 | uint8 check = 0; 51 | for (uint8 const *ptr = reinterpret_cast(this); 52 | ptr < reinterpret_cast(this) + len; 53 | check = static_cast(check + *ptr++)) ; 54 | return !check; 55 | } 56 | 57 | INIT 58 | static Acpi_rsdp *find (mword, unsigned); 59 | 60 | public: 61 | INIT 62 | static void parse(); 63 | }; 64 | -------------------------------------------------------------------------------- /include/acpi_rsdt.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "acpi_table.hpp" 22 | 23 | #pragma pack(1) 24 | 25 | /* 26 | * Root System Description Table (5.2.7 and 5.2.8) 27 | */ 28 | class Acpi_table_rsdt : public Acpi_table 29 | { 30 | private: 31 | static struct table_map 32 | { 33 | uint32 const sig; 34 | Paddr * const ptr; 35 | } map[]; 36 | 37 | unsigned long entries (size_t size) const 38 | { 39 | return (length - sizeof (Acpi_table)) / size; 40 | } 41 | 42 | public: 43 | union 44 | { 45 | uint32 rsdt[]; 46 | uint64 xsdt[]; 47 | }; 48 | 49 | INIT 50 | void parse (Paddr, size_t) const; 51 | }; 52 | 53 | #pragma pack() 54 | -------------------------------------------------------------------------------- /include/acpi_table.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | #include "types.hpp" 23 | 24 | #define SIG(A,B,C,D) (A + (B << 8) + (C << 16) + (D << 24)) 25 | 26 | class Acpi_table 27 | { 28 | public: 29 | uint32 signature; // 0 30 | uint32 length; // 4 31 | uint8 revision; // 8 32 | uint8 checksum; // 9 33 | char oem_id[6]; // 10 34 | char oem_table_id[8]; // 16 35 | uint32 oem_revision; // 24 36 | char creator_id[4]; // 28 37 | uint32 creator_revision; // 32 38 | 39 | INIT 40 | bool good_checksum (Paddr addr) const; 41 | }; 42 | -------------------------------------------------------------------------------- /include/assert.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Assertions 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "console.hpp" 24 | 25 | #ifdef DEBUG 26 | #define assert(X) do { \ 27 | if (EXPECT_FALSE (!(X))) \ 28 | Console::panic ("Assertion \"%s\" failed at %s:%d", #X, __FILE__, __LINE__); \ 29 | } while (0) 30 | #else 31 | #define assert(X) do { (void) sizeof (X); } while (0) 32 | #endif 33 | -------------------------------------------------------------------------------- /include/atomic.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Atomic Operations 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | 23 | class Atomic 24 | { 25 | public: 26 | template 27 | ALWAYS_INLINE 28 | static inline bool cmp_swap (T &ptr, T o, T n) { return __sync_bool_compare_and_swap (&ptr, o, n); } 29 | 30 | template 31 | ALWAYS_INLINE 32 | static inline T add (T &ptr, T v) { return __sync_add_and_fetch (&ptr, v); } 33 | 34 | template 35 | ALWAYS_INLINE 36 | static inline T sub (T &ptr, T v) { return __sync_sub_and_fetch (&ptr, v); } 37 | 38 | template 39 | ALWAYS_INLINE 40 | static inline void set_mask (T &ptr, T v) { __sync_or_and_fetch (&ptr, v); } 41 | 42 | template 43 | ALWAYS_INLINE 44 | static inline void clr_mask (T &ptr, T v) { __sync_and_and_fetch (&ptr, ~v); } 45 | 46 | template 47 | ALWAYS_INLINE 48 | static inline bool test_set_bit (T &val, unsigned long bit) 49 | { 50 | bool ret; 51 | asm volatile ("lock; bts%z1 %2, %1; setc %0" : "=q" (ret), "+m" (val) : "ir" (bit) : "cc"); 52 | return ret; 53 | } 54 | 55 | template 56 | ALWAYS_INLINE 57 | static inline bool test_clr_bit (T &val, unsigned long bit) 58 | { 59 | bool ret; 60 | asm volatile ("lock; btr%z1 %2, %1; setc %0" : "=q" (ret), "+m" (val) : "ir" (bit) : "cc"); 61 | return ret; 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /include/avl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * AVL Tree 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | 23 | class Avl 24 | { 25 | protected: 26 | Avl *lnk[2]; 27 | 28 | explicit Avl() : bal (2) { lnk[0] = lnk[1] = nullptr; } 29 | 30 | private: 31 | unsigned bal; 32 | 33 | bool balanced() const { return bal == 2; } 34 | 35 | static Avl *rotate (Avl *&, bool); 36 | static Avl *rotate (Avl *&, bool, unsigned); 37 | 38 | public: 39 | template static bool insert (Avl **, Avl *); 40 | template static bool remove (Avl **, Avl *); 41 | }; 42 | -------------------------------------------------------------------------------- /include/barrier.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Barriers 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | 23 | ALWAYS_INLINE 24 | inline void barrier() 25 | { 26 | asm volatile ("" : : : "memory"); 27 | } 28 | -------------------------------------------------------------------------------- /include/bits.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Bit Scan Functions 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "types.hpp" 24 | #include "util.hpp" 25 | 26 | ALWAYS_INLINE 27 | inline long int bit_scan_reverse (mword val) 28 | { 29 | if (EXPECT_FALSE (!val)) 30 | return -1; 31 | 32 | asm volatile ("bsr %1, %0" : "=r" (val) : "rm" (val)); 33 | 34 | return val; 35 | } 36 | 37 | ALWAYS_INLINE 38 | inline long int bit_scan_forward (mword val) 39 | { 40 | if (EXPECT_FALSE (!val)) 41 | return -1; 42 | 43 | asm volatile ("bsf %1, %0" : "=r" (val) : "rm" (val)); 44 | 45 | return val; 46 | } 47 | 48 | ALWAYS_INLINE 49 | inline unsigned long max_order (mword base, size_t size) 50 | { 51 | long int o = bit_scan_reverse (size); 52 | 53 | if (base) 54 | o = min (bit_scan_forward (base), o); 55 | 56 | return o; 57 | } 58 | 59 | ALWAYS_INLINE 60 | inline uint64 div64 (uint64 n, uint32 d, uint32 *r) 61 | { 62 | uint64 q; 63 | 64 | #ifdef __i386__ 65 | asm volatile ("divl %5;" 66 | "xchg %1, %2;" 67 | "divl %5;" 68 | "xchg %1, %3;" 69 | : "=A" (q), // quotient 70 | "=r" (*r) // remainder 71 | : "a" (static_cast(n >> 32)), 72 | "d" (0), 73 | "1" (static_cast(n)), 74 | "rm" (d)); 75 | #else 76 | q = n / d; 77 | *r = static_cast(n % d); 78 | #endif 79 | 80 | return q; 81 | } 82 | 83 | ALWAYS_INLINE 84 | static inline mword align_dn (mword val, mword align) 85 | { 86 | val &= ~(align - 1); // Expect power-of-2 87 | return val; 88 | } 89 | 90 | ALWAYS_INLINE 91 | static inline mword align_up (mword val, mword align) 92 | { 93 | val += (align - 1); // Expect power-of-2 94 | return align_dn (val, align); 95 | } 96 | -------------------------------------------------------------------------------- /include/buddy.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Buddy Allocator 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "extern.hpp" 24 | #include "memory.hpp" 25 | #include "spinlock.hpp" 26 | 27 | class Buddy 28 | { 29 | private: 30 | class Block 31 | { 32 | public: 33 | Block * prev; 34 | Block * next; 35 | unsigned short ord; 36 | unsigned short tag; 37 | 38 | enum { 39 | Used = 0, 40 | Free = 1 41 | }; 42 | }; 43 | 44 | Spinlock lock; 45 | signed long max_idx; 46 | signed long min_idx; 47 | mword base; 48 | mword order; 49 | Block * index; 50 | Block * head; 51 | 52 | ALWAYS_INLINE 53 | inline signed long block_to_index (Block *b) 54 | { 55 | return b - index; 56 | } 57 | 58 | ALWAYS_INLINE 59 | inline Block *index_to_block (signed long i) 60 | { 61 | return index + i; 62 | } 63 | 64 | ALWAYS_INLINE 65 | inline signed long page_to_index (mword l_addr) 66 | { 67 | return l_addr / PAGE_SIZE - base / PAGE_SIZE; 68 | } 69 | 70 | ALWAYS_INLINE 71 | inline mword index_to_page (signed long i) 72 | { 73 | return base + i * PAGE_SIZE; 74 | } 75 | 76 | ALWAYS_INLINE 77 | inline mword virt_to_phys (mword virt) 78 | { 79 | return virt - reinterpret_cast(&OFFSET); 80 | } 81 | 82 | ALWAYS_INLINE 83 | inline mword phys_to_virt (mword phys) 84 | { 85 | return phys + reinterpret_cast(&OFFSET); 86 | } 87 | 88 | public: 89 | enum Fill 90 | { 91 | NOFILL, 92 | FILL_0, 93 | FILL_1 94 | }; 95 | 96 | static Buddy allocator; 97 | 98 | INIT 99 | Buddy (mword phys, mword virt, mword f_addr, size_t size); 100 | 101 | void *alloc (unsigned short ord, Fill fill = NOFILL); 102 | 103 | void free (mword addr); 104 | 105 | ALWAYS_INLINE 106 | static inline void *phys_to_ptr (Paddr phys) 107 | { 108 | return reinterpret_cast(allocator.phys_to_virt (static_cast(phys))); 109 | } 110 | 111 | ALWAYS_INLINE 112 | static inline mword ptr_to_phys (void *virt) 113 | { 114 | return allocator.virt_to_phys (reinterpret_cast(virt)); 115 | } 116 | }; 117 | -------------------------------------------------------------------------------- /include/capability.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Capability 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "kobject.hpp" 24 | 25 | class Capability 26 | { 27 | private: 28 | mword val; 29 | 30 | static mword const perm = 0x1f; 31 | 32 | public: 33 | Capability() : val (0) {} 34 | 35 | Capability (Kobject *o, mword a) : val (a ? reinterpret_cast(o) | (a & perm) : 0) {} 36 | 37 | ALWAYS_INLINE 38 | inline Kobject *obj() const { return reinterpret_cast(val & ~perm); } 39 | 40 | ALWAYS_INLINE 41 | inline unsigned prm() const { return val & perm; } 42 | }; 43 | -------------------------------------------------------------------------------- /include/cmdline.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Command Line Parser 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | #include "types.hpp" 23 | 24 | class Cmdline 25 | { 26 | private: 27 | static struct param_map 28 | { 29 | char const *arg; 30 | bool * const ptr; 31 | } map[]; 32 | 33 | INIT 34 | static char *get_arg (char **line); 35 | 36 | public: 37 | static bool iommu; 38 | static bool keyb; 39 | static bool serial; 40 | static bool spinner; 41 | static bool vtlb; 42 | static bool novga; 43 | static bool novpid; 44 | 45 | INIT 46 | static void init (mword); 47 | }; 48 | -------------------------------------------------------------------------------- /include/compiler.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Compiler Macros 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #define STRING(x...) #x 24 | #define EXPAND(x) STRING(x) 25 | 26 | #if defined(__GNUC__) 27 | 28 | #define COMPILER "gcc " __VERSION__ 29 | 30 | #if defined(__GNUC_PATCHLEVEL__) 31 | #define COMPILER_STRING "gcc " EXPAND (__GNUC__) "." EXPAND (__GNUC_MINOR__) "." EXPAND (__GNUC_PATCHLEVEL__) 32 | #define COMPILER_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__) 33 | #else 34 | #define COMPILER_STRING "gcc " EXPAND (__GNUC__) "." EXPAND (__GNUC_MINOR__) 35 | #define COMPILER_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10) 36 | #endif 37 | 38 | #if (COMPILER_VERSION < 430) 39 | #define COLD 40 | #define HOT 41 | #else 42 | #define COLD __attribute__((cold)) 43 | #define HOT __attribute__((hot)) 44 | #endif 45 | 46 | #if (COMPILER_VERSION < 450) 47 | #define UNREACHED __builtin_trap() 48 | #else 49 | #define UNREACHED __builtin_unreachable() 50 | #endif 51 | 52 | #if (COMPILER_VERSION < 460) || !defined(__GXX_EXPERIMENTAL_CXX0X__) 53 | #define nullptr 0 54 | #endif 55 | 56 | #define ALIGNED(X) __attribute__((aligned(X))) 57 | #define ALWAYS_INLINE __attribute__((always_inline)) 58 | #define CPULOCAL __attribute__((section (".cpulocal,\"w\",@nobits#"))) 59 | #define CPULOCAL_HOT __attribute__((section (".cpulocal.hot,\"w\",@nobits#"))) 60 | #define FORMAT(X,Y) __attribute__((format (printf, (X),(Y)))) 61 | #define INIT __attribute__((section (".init"))) 62 | #define INITDATA __attribute__((section (".initdata"))) 63 | #define INIT_PRIORITY(X) __attribute__((init_priority((X)))) 64 | #define NOINLINE __attribute__((noinline)) 65 | #define NONNULL __attribute__((nonnull)) 66 | #define NORETURN __attribute__((noreturn)) 67 | #define PACKED __attribute__((packed)) 68 | #define REGPARM(X) __attribute__((regparm(X))) 69 | #define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) 70 | 71 | #define EXPECT_FALSE(X) __builtin_expect(!!(X), 0) 72 | #define EXPECT_TRUE(X) __builtin_expect(!!(X), 1) 73 | 74 | #define ACCESS_ONCE(x) (*static_cast(&(x))) 75 | 76 | #else 77 | #define COMPILER "unknown compiler" 78 | #define COMPILER_VERSION 0 79 | #endif 80 | -------------------------------------------------------------------------------- /include/config.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Configuration 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #define CFG_VER 6 24 | 25 | #define NUM_CPU 64 26 | #define NUM_IRQ 16 27 | #define NUM_EXC 32 28 | #define NUM_VMI 256 29 | #define NUM_GSI 128 30 | #define NUM_LVT 6 31 | #define NUM_MSI 1 32 | #define NUM_IPI 2 33 | 34 | #define SPN_SCH 0 35 | #define SPN_HLP 1 36 | #define SPN_RCU 2 37 | #define SPN_VFI 4 38 | #define SPN_VFL 5 39 | #define SPN_LVT 7 40 | #define SPN_IPI (SPN_LVT + NUM_LVT) 41 | #define SPN_GSI (SPN_IPI + NUM_IPI + 1) 42 | -------------------------------------------------------------------------------- /include/console.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic Console 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | #include "initprio.hpp" 25 | #include "spinlock.hpp" 26 | 27 | class Console 28 | { 29 | private: 30 | enum 31 | { 32 | MODE_FLAGS = 0, 33 | MODE_WIDTH = 1, 34 | MODE_PRECS = 2, 35 | FLAG_SIGNED = 1UL << 0, 36 | FLAG_ALT_FORM = 1UL << 1, 37 | FLAG_ZERO_PAD = 1UL << 2, 38 | }; 39 | 40 | Console *next; 41 | 42 | static Console *list; 43 | static Spinlock lock; 44 | 45 | virtual void putc (int) = 0; 46 | void print_num (uint64, unsigned, unsigned, unsigned); 47 | void print_str (char const *, unsigned, unsigned); 48 | 49 | FORMAT (2,0) 50 | void vprintf (char const *, va_list); 51 | 52 | protected: 53 | NOINLINE 54 | void enable() 55 | { 56 | Console **ptr; for (ptr = &list; *ptr; ptr = &(*ptr)->next) ; *ptr = this; 57 | } 58 | 59 | public: 60 | FORMAT (1,2) 61 | static void print (char const *, ...); 62 | 63 | FORMAT (1,2) NORETURN 64 | static void panic (char const *, ...); 65 | }; 66 | -------------------------------------------------------------------------------- /include/console_serial.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Serial Console 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "console.hpp" 24 | #include "io.hpp" 25 | 26 | class Console_serial : public Console 27 | { 28 | private: 29 | enum Register 30 | { 31 | THR = 0, // Transmit Holding Register 32 | IER = 1, // Interrupt Enable Register 33 | FCR = 2, // FIFO Control Register 34 | LCR = 3, // Line Control Register 35 | MCR = 4, // Modem Control Register 36 | LSR = 5, // Line Status Register 37 | DLL = 0, // Divisor Latch (LSB) 38 | DLM = 1, // Divisor Latch (MSB) 39 | }; 40 | 41 | static unsigned const freq = 115200; 42 | 43 | unsigned base; 44 | 45 | ALWAYS_INLINE 46 | inline unsigned in (Register r) { return Io::in(base + r); } 47 | 48 | ALWAYS_INLINE 49 | inline void out (Register r, unsigned v) { Io::out (base + r, static_cast(v)); } 50 | 51 | void putc (int c); 52 | 53 | public: 54 | INIT 55 | Console_serial(); 56 | 57 | static Console_serial con; 58 | }; 59 | -------------------------------------------------------------------------------- /include/console_vga.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * VGA Console 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "console.hpp" 24 | #include "io.hpp" 25 | #include "memory.hpp" 26 | #include "string.hpp" 27 | 28 | class Console_vga : public Console 29 | { 30 | private: 31 | enum Register 32 | { 33 | START_ADDR_HI = 0xc, 34 | START_ADDR_LO = 0xd 35 | }; 36 | 37 | unsigned num, row, col; 38 | 39 | ALWAYS_INLINE 40 | static inline unsigned read (Register reg) 41 | { 42 | Io::out(0x3d4, reg); 43 | return Io::in(0x3d5); 44 | } 45 | 46 | ALWAYS_INLINE 47 | static inline void write (Register reg, uint8 val) 48 | { 49 | Io::out(0x3d4, reg); 50 | Io::out(0x3d5, val); 51 | } 52 | 53 | ALWAYS_INLINE 54 | inline void clear_all() 55 | { 56 | memset (reinterpret_cast(HV_GLOBAL_FBUF), 0, 160 * num); 57 | } 58 | 59 | ALWAYS_INLINE 60 | inline void clear_row (unsigned r) 61 | { 62 | memcpy (reinterpret_cast(HV_GLOBAL_FBUF), reinterpret_cast(HV_GLOBAL_FBUF + 160), 160 * r); 63 | memset (reinterpret_cast(HV_GLOBAL_FBUF + 160 * r), 0, 160); 64 | } 65 | 66 | void putc (int c); 67 | 68 | public: 69 | enum Color 70 | { 71 | COLOR_BLACK = 0x0, 72 | COLOR_BLUE = 0x1, 73 | COLOR_GREEN = 0x2, 74 | COLOR_CYAN = 0x3, 75 | COLOR_RED = 0x4, 76 | COLOR_MAGENTA = 0x5, 77 | COLOR_YELLOW = 0x6, 78 | COLOR_WHITE = 0x7, 79 | COLOR_LIGHT_BLACK = 0x8, 80 | COLOR_LIGHT_BLUE = 0x9, 81 | COLOR_LIGHT_GREEN = 0xa, 82 | COLOR_LIGHT_CYAN = 0xb, 83 | COLOR_LIGHT_RED = 0xc, 84 | COLOR_LIGHT_MAGENTA = 0xd, 85 | COLOR_LIGHT_YELLOW = 0xe, 86 | COLOR_LIGHT_WHITE = 0xf 87 | }; 88 | 89 | INIT 90 | Console_vga(); 91 | 92 | INIT 93 | void setup(); 94 | 95 | ALWAYS_INLINE 96 | inline unsigned spinner (unsigned id) { return id < 25 - num ? 24 - id : 0; } 97 | 98 | ALWAYS_INLINE 99 | inline void put (unsigned long r, unsigned long c, Color color, int x) 100 | { 101 | *reinterpret_cast(HV_GLOBAL_FBUF + r * 160 + c * 2) = static_cast(color << 8 | x); 102 | } 103 | 104 | ALWAYS_INLINE 105 | static inline void set_page (unsigned page) 106 | { 107 | page <<= 11; // due to odd/even addressing 108 | write (START_ADDR_HI, static_cast(page >> 8)); 109 | write (START_ADDR_LO, static_cast(page)); 110 | } 111 | 112 | static Console_vga con; 113 | }; 114 | -------------------------------------------------------------------------------- /include/counter.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Event Counters 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "config.hpp" 24 | #include "console_vga.hpp" 25 | #include "cpu.hpp" 26 | 27 | class Counter 28 | { 29 | public: 30 | static unsigned ipi[NUM_IPI] CPULOCAL; 31 | static unsigned lvt[NUM_LVT] CPULOCAL; 32 | static unsigned gsi[NUM_GSI] CPULOCAL; 33 | static unsigned exc[NUM_EXC] CPULOCAL; 34 | static unsigned vmi[NUM_VMI] CPULOCAL; 35 | static unsigned vtlb_gpf CPULOCAL; 36 | static unsigned vtlb_hpf CPULOCAL; 37 | static unsigned vtlb_fill CPULOCAL; 38 | static unsigned vtlb_flush CPULOCAL; 39 | static unsigned schedule CPULOCAL; 40 | static unsigned helping CPULOCAL; 41 | static uint64 cycles_idle CPULOCAL; 42 | 43 | static void dump(); 44 | 45 | ALWAYS_INLINE 46 | static inline unsigned remote (unsigned c, unsigned i) 47 | { 48 | return *reinterpret_cast(reinterpret_cast(ipi + i) - CPU_LOCAL_DATA + HV_GLOBAL_CPUS + c * PAGE_SIZE); 49 | } 50 | 51 | template 52 | static void print (mword val, Console_vga::Color c, unsigned col) 53 | { 54 | if (EXPECT_FALSE (Cpu::row)) 55 | for (unsigned i = 0; i < D; i++, val /= B) 56 | Console_vga::con.put (Cpu::row, col - i, c, !i || val ? (val % B)["0123456789ABCDEF"] : ' '); 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /include/cpuset.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * CPU Set 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "atomic.hpp" 24 | #include "types.hpp" 25 | 26 | class Cpuset 27 | { 28 | private: 29 | mword val; 30 | 31 | public: 32 | ALWAYS_INLINE 33 | inline explicit Cpuset() : val (0) {} 34 | 35 | ALWAYS_INLINE 36 | inline bool chk (unsigned cpu) const { return val & 1UL << cpu; } 37 | 38 | ALWAYS_INLINE 39 | inline bool set (unsigned cpu) { return !Atomic::test_set_bit (val, cpu); } 40 | 41 | ALWAYS_INLINE 42 | inline void clr (unsigned cpu) { Atomic::clr_mask (val, 1UL << cpu); } 43 | 44 | ALWAYS_INLINE 45 | inline void merge (Cpuset &s) { Atomic::set_mask (val, s.val); } 46 | }; 47 | -------------------------------------------------------------------------------- /include/crd.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Capability Range Descriptor (CRD) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "compiler.hpp" 24 | #include "types.hpp" 25 | 26 | class Crd 27 | { 28 | private: 29 | mword val; 30 | 31 | public: 32 | enum Type 33 | { 34 | MEM = 1, 35 | PIO = 2, 36 | OBJ = 3, 37 | }; 38 | 39 | ALWAYS_INLINE 40 | inline explicit Crd() : val (0) {} 41 | 42 | ALWAYS_INLINE 43 | inline explicit Crd (mword v) : val (v) {} 44 | 45 | ALWAYS_INLINE 46 | inline explicit Crd (Type t, mword b = 0, mword o = 0x1f, mword a = 0x1f) : val (b << 12 | o << 7 | a << 2 | t) {} 47 | 48 | ALWAYS_INLINE 49 | inline Type type() const { return static_cast(val & 0x3); } 50 | 51 | ALWAYS_INLINE 52 | inline unsigned attr() const { return val >> 2 & 0x1f; } 53 | 54 | ALWAYS_INLINE 55 | inline unsigned order() const { return val >> 7 & 0x1f; } 56 | 57 | ALWAYS_INLINE 58 | inline mword base() const { return val >> 12; } 59 | }; 60 | 61 | class Xfer : public Crd 62 | { 63 | private: 64 | mword val; 65 | 66 | public: 67 | ALWAYS_INLINE 68 | inline explicit Xfer (Crd c, mword v) : Crd (c), val (v) {} 69 | 70 | ALWAYS_INLINE 71 | inline mword flags() const { return val & 0xfff; } 72 | 73 | ALWAYS_INLINE 74 | inline mword hotspot() const { return val >> 12; } 75 | }; 76 | -------------------------------------------------------------------------------- /include/descriptor.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Descriptor 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | #include "types.hpp" 23 | 24 | class Descriptor 25 | { 26 | protected: 27 | enum Granularity 28 | { 29 | BYTES = 0u << 23, 30 | PAGES = 1u << 23, 31 | }; 32 | 33 | enum Size 34 | { 35 | BIT_16 = 0u << 22, 36 | BIT_32 = 1u << 22 37 | }; 38 | 39 | enum Type 40 | { 41 | SYS_LDT = 2u << 8, 42 | SYS_TASK_GATE = 5u << 8, 43 | SYS_TSS = 9u << 8, 44 | SYS_CALL_GATE = 12u << 8, 45 | SYS_INTR_GATE = 14u << 8, 46 | SYS_TRAP_GATE = 15u << 8, 47 | 48 | DATA_R = 16u << 8, 49 | DATA_RA = 17u << 8, 50 | DATA_RW = 18u << 8, 51 | DATA_RWA = 19u << 8, 52 | DATA_DOWN_R = 20u << 8, 53 | DATA_DOWN_RA = 21u << 8, 54 | DATA_DOWN_RW = 22u << 8, 55 | DATA_DOWN_RWA = 23u << 8, 56 | 57 | CODE_X = 24u << 8, 58 | CODE_XA = 25u << 8, 59 | CODE_XR = 26u << 8, 60 | CODE_XRA = 27u << 8, 61 | CODE_CONF_X = 28u << 8, 62 | CODE_CONF_XA = 29u << 8, 63 | CODE_CONF_XR = 30u << 8, 64 | CODE_CONF_XRA = 31u << 8 65 | }; 66 | }; 67 | 68 | #pragma pack(1) 69 | class Pseudo_descriptor 70 | { 71 | private: 72 | uint16 limit; 73 | mword base; 74 | 75 | public: 76 | ALWAYS_INLINE 77 | inline Pseudo_descriptor (mword l, mword b) : limit (static_cast(l)), base (b) {} 78 | }; 79 | #pragma pack() 80 | -------------------------------------------------------------------------------- /include/dpt.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * DMA Page Table (DPT) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "pte.hpp" 24 | 25 | class Dpt : public Pte 26 | { 27 | public: 28 | static mword ord; 29 | 30 | enum 31 | { 32 | DPT_R = 1UL << 0, 33 | DPT_W = 1UL << 1, 34 | DPT_S = 1UL << 7, 35 | 36 | PTE_P = DPT_R | DPT_W, 37 | PTE_S = DPT_S, 38 | PTE_N = DPT_R | DPT_W, 39 | }; 40 | }; 41 | -------------------------------------------------------------------------------- /include/elf.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Executable and Linkable Format (ELF) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "compiler.hpp" 24 | 25 | class Eh 26 | { 27 | public: 28 | uint32 ei_magic; 29 | uint8 ei_class, ei_data, ei_version, ei_osabi, ei_abiversion, ei_pad[7]; 30 | uint16 type, machine; 31 | uint32 version; 32 | mword entry, ph_offset, sh_offset; 33 | uint32 flags; 34 | uint16 eh_size, ph_size, ph_count, sh_size, sh_count, strtab; 35 | }; 36 | 37 | class Ph32 38 | { 39 | public: 40 | uint32 type, f_offs, v_addr, p_addr, f_size, m_size, flags, align; 41 | }; 42 | 43 | class Ph64 44 | { 45 | public: 46 | uint32 type, flags; 47 | uint64 f_offs, v_addr, p_addr, f_size, m_size, align; 48 | }; 49 | -------------------------------------------------------------------------------- /include/ept.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Extended Page Table (EPT) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "assert.hpp" 24 | #include "pte.hpp" 25 | 26 | class Ept : public Pte 27 | { 28 | public: 29 | static mword ord; 30 | 31 | enum 32 | { 33 | EPT_R = 1UL << 0, 34 | EPT_W = 1UL << 1, 35 | EPT_X = 1UL << 2, 36 | EPT_I = 1UL << 6, 37 | EPT_S = 1UL << 7, 38 | 39 | PTE_P = EPT_R | EPT_W | EPT_X, 40 | PTE_S = EPT_S, 41 | PTE_N = EPT_R | EPT_W | EPT_X, 42 | }; 43 | 44 | ALWAYS_INLINE 45 | static inline mword hw_attr (mword a, mword t) { return a ? t << 3 | a | EPT_I | EPT_R : 0; } 46 | 47 | ALWAYS_INLINE 48 | inline mword order() const { return PAGE_BITS + (static_cast(val) >> 8 & 0xf); } 49 | 50 | ALWAYS_INLINE 51 | static inline mword order (mword o) { return o << 8; } 52 | 53 | ALWAYS_INLINE 54 | inline void flush() 55 | { 56 | struct { uint64 eptp, rsvd; } desc = { addr() | (max() - 1) << 3 | 6, 0 }; 57 | 58 | bool ret; 59 | asm volatile ("invept %1, %2; seta %0" : "=q" (ret) : "m" (desc), "r" (1UL) : "cc", "memory"); 60 | assert (ret); 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /include/extern.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * External Symbols 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "types.hpp" 24 | 25 | extern char GIT_VER; 26 | 27 | extern char PAGE_0; 28 | extern char PAGE_1; 29 | extern char PAGE_H; 30 | 31 | extern char FRAME_0; 32 | extern char FRAME_1; 33 | extern char FRAME_H; 34 | 35 | extern char PDBR; 36 | 37 | extern char LINK_P; 38 | extern char LINK_E; 39 | extern char LOAD_E; 40 | extern char OFFSET; 41 | 42 | extern mword FIXUP_S; 43 | extern mword FIXUP_E; 44 | 45 | extern void (*CTORS_L)(); 46 | extern void (*CTORS_C)(); 47 | extern void (*CTORS_G)(); 48 | extern void (*CTORS_E)(); 49 | 50 | extern char entry_sysenter; 51 | extern char entry_vmx; 52 | extern mword handlers[]; 53 | extern mword hwdev_addr; 54 | -------------------------------------------------------------------------------- /include/fpu.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Floating Point Unit (FPU) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "cpu.hpp" 24 | #include "hazards.hpp" 25 | #include "slab.hpp" 26 | #include "x86.hpp" 27 | 28 | class Fpu 29 | { 30 | private: 31 | char data[512]; 32 | 33 | static Slab_cache cache; 34 | 35 | public: 36 | ALWAYS_INLINE 37 | inline void save() { asm volatile ("fxsave %0" : "=m" (*data)); } 38 | 39 | ALWAYS_INLINE 40 | inline void load() { asm volatile ("fxrstor %0" : : "m" (*data)); } 41 | 42 | ALWAYS_INLINE 43 | static inline void init() { asm volatile ("fninit"); } 44 | 45 | ALWAYS_INLINE 46 | static inline void enable() { asm volatile ("clts"); Cpu::hazard |= HZD_FPU; } 47 | 48 | ALWAYS_INLINE 49 | static inline void disable() { set_cr0 (get_cr0() | Cpu::CR0_TS); Cpu::hazard &= ~HZD_FPU; } 50 | 51 | ALWAYS_INLINE 52 | static inline void *operator new (size_t) { return cache.alloc(); } 53 | 54 | ALWAYS_INLINE 55 | static inline void operator delete (void *ptr) { cache.free (ptr); } 56 | }; 57 | -------------------------------------------------------------------------------- /include/gdt.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Global Descriptor Table (GDT) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "descriptor.hpp" 24 | #include "selectors.hpp" 25 | 26 | class Gdt : public Descriptor 27 | { 28 | private: 29 | uint32 val[2]; 30 | 31 | ALWAYS_INLINE 32 | inline void set32 (Type type, Granularity gran, Size size, bool l, unsigned dpl, mword base, mword limit) 33 | { 34 | val[0] = static_cast(base << 16 | (limit & 0xffff)); 35 | val[1] = static_cast((base & 0xff000000) | gran | size | (limit & 0xf0000) | l << 21 | 1u << 15 | dpl << 13 | type | (base >> 16 & 0xff)); 36 | } 37 | 38 | #ifdef __x86_64__ 39 | ALWAYS_INLINE 40 | inline void set64 (Type type, Granularity gran, Size size, bool l, unsigned dpl, mword base, mword limit) 41 | { 42 | set32 (type, gran, size, l, dpl, base, limit); 43 | (this + 1)->val[0] = static_cast(base >> 32); 44 | (this + 1)->val[1] = 0; 45 | } 46 | #endif 47 | 48 | public: 49 | static Gdt gdt[SEL_MAX >> 3] CPULOCAL; 50 | 51 | static void build(); 52 | 53 | ALWAYS_INLINE 54 | static inline void load() 55 | { 56 | asm volatile ("lgdt %0" : : "m" (Pseudo_descriptor (sizeof (gdt) - 1, reinterpret_cast(gdt)))); 57 | } 58 | 59 | ALWAYS_INLINE 60 | static inline void unbusy_tss() 61 | { 62 | gdt[SEL_TSS_RUN >> 3].val[1] &= ~0x200; 63 | } 64 | }; 65 | -------------------------------------------------------------------------------- /include/gsi.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Global System Interrupts (GSI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "assert.hpp" 24 | #include "config.hpp" 25 | 26 | class Ioapic; 27 | class Sm; 28 | 29 | class Gsi 30 | { 31 | public: 32 | Sm * sm; 33 | Ioapic * ioapic; 34 | union { 35 | uint16 irt; 36 | struct { 37 | uint8 vec; 38 | uint8 dlv:3, dst:1, sts:1, pol:1, irr:1, trg:1; 39 | }; 40 | }; 41 | 42 | static Gsi gsi_table[NUM_GSI]; 43 | static unsigned irq_table[NUM_IRQ]; 44 | 45 | INIT 46 | static void setup(); 47 | 48 | static uint64 set (unsigned, unsigned = 0, unsigned = 0); 49 | 50 | static void mask (unsigned); 51 | static void unmask (unsigned); 52 | 53 | ALWAYS_INLINE 54 | static inline unsigned irq_to_gsi (unsigned irq) 55 | { 56 | assert (irq < NUM_IRQ); 57 | return irq_table[irq]; 58 | } 59 | 60 | REGPARM (1) 61 | static void vector (unsigned) asm ("gsi_vector"); 62 | }; 63 | -------------------------------------------------------------------------------- /include/hazards.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Hazards 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #define HZD_SCHED 0x1 22 | #define HZD_DS_ES 0x2 23 | #define HZD_TR 0x4 24 | #define HZD_FPU 0x8 25 | #define HZD_RCU 0x10 26 | #define HZD_TSC 0x20000000 27 | #define HZD_STEP 0x40000000 28 | #define HZD_RECALL 0x80000000 29 | -------------------------------------------------------------------------------- /include/hip.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Hypervisor Information Page (HIP) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "atomic.hpp" 24 | #include "config.hpp" 25 | #include "extern.hpp" 26 | 27 | class Hip_cpu 28 | { 29 | public: 30 | uint8 flags; 31 | uint8 thread; 32 | uint8 core; 33 | uint8 package; 34 | uint32 reserved; 35 | }; 36 | 37 | class Hip_mem 38 | { 39 | public: 40 | enum { 41 | HYPERVISOR = -1u, 42 | MB_MODULE = -2u 43 | }; 44 | 45 | uint64 addr; 46 | uint64 size; 47 | uint32 type; 48 | uint32 aux; 49 | }; 50 | 51 | class Hip 52 | { 53 | private: 54 | uint32 signature; // 0x0 55 | uint16 checksum; // 0x4 56 | uint16 length; // 0x6 57 | uint16 cpu_offs; // 0x8 58 | uint16 cpu_size; // 0xa 59 | uint16 mem_offs; // 0xc 60 | uint16 mem_size; // 0xe 61 | uint32 api_flg; // 0x10 62 | uint32 api_ver; // 0x14 63 | uint32 sel_num; // 0x18 64 | uint32 sel_exc; // 0x1c 65 | uint32 sel_vmi; // 0x20 66 | uint32 sel_gsi; // 0x24 67 | uint32 cfg_page; // 0x28 68 | uint32 cfg_utcb; // 0x2c 69 | uint32 freq_tsc; // 0x30 70 | uint32 freq_bus; // 0x34 71 | Hip_cpu cpu_desc[NUM_CPU]; 72 | Hip_mem mem_desc[]; 73 | 74 | public: 75 | enum Feature { 76 | FEAT_VMX = 1u << 1, 77 | FEAT_SVM = 1u << 2, 78 | }; 79 | 80 | static mword root_addr; 81 | static mword root_size; 82 | 83 | ALWAYS_INLINE 84 | static inline Hip *hip() 85 | { 86 | return reinterpret_cast(&PAGE_H); 87 | } 88 | 89 | static uint32 feature() 90 | { 91 | return hip()->api_flg; 92 | } 93 | 94 | static void remove (Feature f) 95 | { 96 | Atomic::clr_mask (hip()->api_flg, static_castapi_flg>(f)); 97 | } 98 | 99 | static bool cpu_online (unsigned long cpu) 100 | { 101 | return cpu < NUM_CPU && hip()->cpu_desc[cpu].flags & 1; 102 | } 103 | 104 | INIT 105 | static void build (mword); 106 | 107 | INIT 108 | static void add_mem (Hip_mem *&, mword, size_t); 109 | 110 | INIT 111 | static void add_mod (Hip_mem *&, mword, size_t); 112 | 113 | INIT 114 | static void add_mhv (Hip_mem *&); 115 | 116 | static void add_cpu(); 117 | static void add_check(); 118 | }; 119 | -------------------------------------------------------------------------------- /include/hpet.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * High Precision Event Timer (HPET) 3 | * 4 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 5 | * 6 | * This file is part of the NOVA microhypervisor. 7 | * 8 | * NOVA is free software: you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License version 2 as 10 | * published by the Free Software Foundation. 11 | * 12 | * NOVA is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License version 2 for more details. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "list.hpp" 21 | #include "slab.hpp" 22 | 23 | class Hpet : public List 24 | { 25 | private: 26 | Paddr const phys; 27 | unsigned const id; 28 | uint16 rid; 29 | 30 | static Hpet * list; 31 | static Slab_cache cache; 32 | 33 | public: 34 | ALWAYS_INLINE 35 | explicit inline Hpet (Paddr p, unsigned i) : List (list), phys (p), id (i), rid (0) {} 36 | 37 | ALWAYS_INLINE 38 | static inline void *operator new (size_t) { return cache.alloc(); } 39 | 40 | ALWAYS_INLINE 41 | static inline bool claim_dev (unsigned r, unsigned i) 42 | { 43 | for (Hpet *hpet = list; hpet; hpet = hpet->next) 44 | if (hpet->rid == 0 && hpet->id == i) { 45 | hpet->rid = static_cast(r); 46 | return true; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | ALWAYS_INLINE 53 | static inline unsigned phys_to_rid (Paddr p) 54 | { 55 | for (Hpet *hpet = list; hpet; hpet = hpet->next) 56 | if (hpet->phys == p) 57 | return hpet->rid; 58 | 59 | return ~0U; 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /include/hpt.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Host Page Table (HPT) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "arch.hpp" 24 | #include "pte.hpp" 25 | 26 | class Hpt : public Pte 27 | { 28 | private: 29 | ALWAYS_INLINE 30 | static inline void flush() 31 | { 32 | mword cr3; 33 | asm volatile ("mov %%cr3, %0; mov %0, %%cr3" : "=&r" (cr3)); 34 | } 35 | 36 | ALWAYS_INLINE 37 | static inline void flush (mword addr) 38 | { 39 | asm volatile ("invlpg %0" : : "m" (*reinterpret_cast(addr))); 40 | } 41 | 42 | public: 43 | static mword ord; 44 | 45 | enum 46 | { 47 | HPT_P = 1UL << 0, 48 | HPT_W = 1UL << 1, 49 | HPT_U = 1UL << 2, 50 | HPT_UC = 1UL << 4, 51 | HPT_A = 1UL << 5, 52 | HPT_D = 1UL << 6, 53 | HPT_S = 1UL << 7, 54 | HPT_G = 1UL << 8, 55 | HPT_NX = 0, 56 | 57 | PTE_P = HPT_P, 58 | PTE_S = HPT_S, 59 | PTE_N = HPT_A | HPT_U | HPT_W | HPT_P, 60 | }; 61 | 62 | ALWAYS_INLINE 63 | inline Paddr addr() const { return static_cast(val) & ~PAGE_MASK; } 64 | 65 | ALWAYS_INLINE 66 | static inline mword hw_attr (mword a) { return a ? a | HPT_D | HPT_A | HPT_U | HPT_P : 0; } 67 | 68 | ALWAYS_INLINE 69 | static inline mword current() 70 | { 71 | mword addr; 72 | asm volatile ("mov %%cr3, %0" : "=r" (addr)); 73 | return addr; 74 | } 75 | 76 | ALWAYS_INLINE 77 | inline void make_current() 78 | { 79 | asm volatile ("mov %0, %%cr3" : : "r" (val) : "memory"); 80 | } 81 | 82 | bool sync_from (Hpt, mword, mword); 83 | 84 | void sync_master_range (mword, mword); 85 | 86 | Paddr replace (mword, mword); 87 | 88 | static void *remap (Paddr); 89 | }; 90 | 91 | class Hptp : public Hpt 92 | { 93 | public: 94 | ALWAYS_INLINE 95 | inline explicit Hptp (mword v = 0) { val = v; } 96 | }; 97 | -------------------------------------------------------------------------------- /include/idt.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Interrupt Descriptor Table (IDT) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "descriptor.hpp" 24 | #include "vectors.hpp" 25 | 26 | class Idt : public Descriptor 27 | { 28 | private: 29 | uint32 val[sizeof (mword) / 2]; 30 | 31 | ALWAYS_INLINE 32 | inline void set (Type type, unsigned dpl, unsigned selector, mword offset) 33 | { 34 | val[0] = static_cast(selector << 16 | (offset & 0xffff)); 35 | val[1] = static_cast((offset & 0xffff0000) | 1u << 15 | dpl << 13 | type); 36 | #ifdef __x86_64__ 37 | val[2] = static_cast(offset >> 32); 38 | #endif 39 | } 40 | 41 | public: 42 | static Idt idt[VEC_MAX]; 43 | 44 | INIT 45 | static void build(); 46 | 47 | ALWAYS_INLINE 48 | static inline void load() 49 | { 50 | asm volatile ("lidt %0" : : "m" (Pseudo_descriptor (sizeof (idt) - 1, reinterpret_cast(idt)))); 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /include/initprio.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Static Initialization Priorities 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #define AFTER(X) (X + 1) 24 | 25 | #define PRIO_GLOBAL 100 26 | #define PRIO_BUDDY AFTER (PRIO_GLOBAL) 27 | #define PRIO_SLAB AFTER (PRIO_BUDDY) 28 | #define PRIO_CONSOLE 0xfffd 29 | #define PRIO_LOCAL 0xfffe 30 | -------------------------------------------------------------------------------- /include/io.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * I/O Ports 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | 23 | class Io 24 | { 25 | public: 26 | template 27 | ALWAYS_INLINE 28 | static inline unsigned in (unsigned port) 29 | { 30 | T val; 31 | asm volatile ("in %w1, %0" : "=a" (val) : "Nd" (port)); 32 | return val; 33 | } 34 | 35 | template 36 | ALWAYS_INLINE 37 | static inline void out (unsigned port, T val) 38 | { 39 | asm volatile ("out %0, %w1" : : "a" (val), "Nd" (port)); 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /include/keyb.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Keyboard 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "io.hpp" 24 | 25 | class Keyb 26 | { 27 | private: 28 | enum 29 | { 30 | STS_OUTB = 1U << 0, 31 | STS_AUXB = 1U << 5, 32 | }; 33 | 34 | ALWAYS_INLINE 35 | static inline unsigned output() { return Io::in(0x60); } 36 | 37 | ALWAYS_INLINE 38 | static inline unsigned status() { return Io::in(0x64); } 39 | 40 | public: 41 | static unsigned const irq = 1; 42 | static unsigned gsi; 43 | 44 | INIT 45 | static void init(); 46 | 47 | static void interrupt(); 48 | }; 49 | -------------------------------------------------------------------------------- /include/kobject.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Kernel Object 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "mdb.hpp" 24 | #include "refptr.hpp" 25 | 26 | class Kobject : public Mdb 27 | { 28 | private: 29 | uint8 objtype; 30 | 31 | static void free (Rcu_elem *) {} 32 | 33 | protected: 34 | Spinlock lock; 35 | 36 | enum Type 37 | { 38 | PD, 39 | EC, 40 | SC, 41 | PT, 42 | SM, 43 | INVALID, 44 | }; 45 | 46 | explicit Kobject (Type t, Space *s, mword b = 0, mword a = 0) : Mdb (s, reinterpret_cast(this), b, a, free), objtype (t) {} 47 | 48 | public: 49 | ALWAYS_INLINE 50 | inline Type type() const 51 | { 52 | return EXPECT_TRUE (this) ? Type (objtype) : INVALID; 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /include/list.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * List Element 3 | * 4 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 5 | * 6 | * This file is part of the NOVA microhypervisor. 7 | * 8 | * NOVA is free software: you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License version 2 as 10 | * published by the Free Software Foundation. 11 | * 12 | * NOVA is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License version 2 for more details. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "compiler.hpp" 21 | 22 | template 23 | class List 24 | { 25 | protected: 26 | T *next; 27 | 28 | public: 29 | ALWAYS_INLINE 30 | explicit inline List (T *&list) : next (nullptr) 31 | { 32 | T **ptr; for (ptr = &list; *ptr; ptr = &(*ptr)->next) ; *ptr = static_cast(this); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /include/lock_guard.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic Lock Guard 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | 23 | template 24 | class Lock_guard 25 | { 26 | private: 27 | T &_lock; 28 | 29 | public: 30 | ALWAYS_INLINE 31 | inline Lock_guard (T &l) : _lock (l) 32 | { 33 | _lock.lock(); 34 | } 35 | 36 | ALWAYS_INLINE 37 | inline ~Lock_guard() 38 | { 39 | _lock.unlock(); 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /include/mca.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Machine-Check Architecture (MCA) 3 | * 4 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 5 | * 6 | * This file is part of the NOVA microhypervisor. 7 | * 8 | * NOVA is free software: you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License version 2 as 10 | * published by the Free Software Foundation. 11 | * 12 | * NOVA is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License version 2 for more details. 16 | */ 17 | 18 | #pragma once 19 | 20 | class Mca 21 | { 22 | private: 23 | static unsigned banks CPULOCAL; 24 | 25 | public: 26 | static void init(); 27 | static void vector(); 28 | }; 29 | -------------------------------------------------------------------------------- /include/mdb.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Mapping Database 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "avl.hpp" 24 | #include "rcu.hpp" 25 | #include "slab.hpp" 26 | #include "util.hpp" 27 | 28 | class Space; 29 | 30 | class Mdb : public Avl, public Rcu_elem 31 | { 32 | private: 33 | static Slab_cache cache; 34 | static Spinlock lock; 35 | 36 | bool alive() const { return prev->next == this && next->prev == this; } 37 | 38 | static void free (Rcu_elem *e) 39 | { 40 | Mdb *m = static_cast(e); 41 | delete m; 42 | } 43 | 44 | public: 45 | Spinlock node_lock; 46 | uint16 dpth; 47 | Mdb * prev; 48 | Mdb * next; 49 | Mdb * prnt; 50 | Space * const space; 51 | mword const node_phys; 52 | mword const node_base; 53 | mword const node_order; 54 | mword node_attr; 55 | mword const node_type; 56 | mword const node_sub; 57 | 58 | ALWAYS_INLINE 59 | inline bool larger (Mdb *x) const { return node_base > x->node_base; } 60 | 61 | ALWAYS_INLINE 62 | inline bool equal (Mdb *x) const { return (node_base ^ x->node_base) >> max (node_order, x->node_order) == 0; } 63 | 64 | NOINLINE 65 | explicit Mdb (Space *s, mword p, mword b, mword a, void (*f)(Rcu_elem *)) : Rcu_elem (f), dpth (0), prev (this), next (this), prnt (nullptr), space (s), node_phys (p), node_base (b), node_order (0), node_attr (a), node_type (0), node_sub (0) {} 66 | 67 | NOINLINE 68 | explicit Mdb (Space *s, mword p, mword b, mword o = 0, mword a = 0, mword t = 0, mword sub = 0) : Rcu_elem (free), dpth (0), prev (this), next (this), prnt (nullptr), space (s), node_phys (p), node_base (b), node_order (o), node_attr (a), node_type (t), node_sub (sub) {} 69 | 70 | static Mdb *lookup (Avl *tree, mword base, bool next) 71 | { 72 | Mdb *n = nullptr; 73 | bool d; 74 | 75 | for (Mdb *m = static_cast(tree); m; m = static_cast(m->lnk[d])) { 76 | 77 | if ((m->node_base ^ base) >> m->node_order == 0) 78 | return m; 79 | 80 | if ((d = base > m->node_base) == 0 && next) 81 | n = m; 82 | } 83 | 84 | return n; 85 | } 86 | 87 | bool insert_node (Mdb *, mword); 88 | void demote_node (mword); 89 | bool remove_node(); 90 | 91 | ALWAYS_INLINE 92 | static inline void *operator new (size_t) { return cache.alloc(); } 93 | 94 | ALWAYS_INLINE 95 | static inline void operator delete (void *ptr) { cache.free (ptr); } 96 | }; 97 | -------------------------------------------------------------------------------- /include/memory.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Virtual-Memory Layout 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #define PAGE_BITS 12 24 | #define PAGE_SIZE (1 << PAGE_BITS) 25 | #define PAGE_MASK (PAGE_SIZE - 1) 26 | 27 | #define LOAD_ADDR 0x200000 28 | 29 | #if defined(__i386__) 30 | #define USER_ADDR 0xc0000000 31 | #define LINK_ADDR 0xc0000000 32 | #define CPU_LOCAL 0xcfc00000 33 | #define SPC_LOCAL 0xd0000000 34 | #elif defined(__x86_64__) 35 | #define USER_ADDR 0x00007ffffffff000 36 | #define LINK_ADDR 0xffffffff81000000 37 | #define CPU_LOCAL 0xffffffffbfe00000 38 | #define SPC_LOCAL 0xffffffffc0000000 39 | #endif 40 | 41 | #define HV_GLOBAL_CPUS (CPU_LOCAL - 0x1000000) 42 | #define HV_GLOBAL_FBUF (CPU_LOCAL - PAGE_SIZE * 1) 43 | 44 | #define CPU_LOCAL_STCK (SPC_LOCAL - PAGE_SIZE * 3) 45 | #define CPU_LOCAL_APIC (SPC_LOCAL - PAGE_SIZE * 2) 46 | #define CPU_LOCAL_DATA (SPC_LOCAL - PAGE_SIZE * 1) 47 | 48 | #define SPC_LOCAL_IOP (SPC_LOCAL) 49 | #define SPC_LOCAL_IOP_E (SPC_LOCAL_IOP + PAGE_SIZE * 2) 50 | #define SPC_LOCAL_REMAP (SPC_LOCAL_OBJ - 0x1000000) 51 | #define SPC_LOCAL_OBJ (END_SPACE_LIM - 0x20000000) 52 | 53 | #define END_SPACE_LIM (~0UL + 1) 54 | -------------------------------------------------------------------------------- /include/mtd.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Message Transfer Descriptor (MTD) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | #include "types.hpp" 23 | 24 | class Mtd 25 | { 26 | public: 27 | mword val; 28 | 29 | enum Item 30 | { 31 | // IPC 32 | GPR_ACDB = 1ul << 0, 33 | GPR_BSD = 1ul << 1, 34 | RSP = 1ul << 2, 35 | RIP_LEN = 1ul << 3, 36 | RFLAGS = 1ul << 4, 37 | DS_ES = 1ul << 5, 38 | FS_GS = 1ul << 6, 39 | CS_SS = 1ul << 7, 40 | TR = 1ul << 8, 41 | LDTR = 1ul << 9, 42 | GDTR = 1ul << 10, 43 | IDTR = 1ul << 11, 44 | CR = 1ul << 12, 45 | DR = 1ul << 13, 46 | SYSENTER = 1ul << 14, 47 | QUAL = 1ul << 15, 48 | CTRL = 1ul << 16, 49 | INJ = 1ul << 17, 50 | STA = 1ul << 18, 51 | TSC = 1ul << 19, 52 | EFER = 1ul << 20, 53 | }; 54 | 55 | ALWAYS_INLINE 56 | inline explicit Mtd (mword v) : val (v) {} 57 | }; 58 | -------------------------------------------------------------------------------- /include/mtrr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Memory Type Range Registers (MTRR) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bits.hpp" 24 | #include "list.hpp" 25 | #include "slab.hpp" 26 | 27 | class Mtrr : public List 28 | { 29 | private: 30 | uint64 const base; 31 | uint64 const mask; 32 | 33 | static unsigned count; 34 | static unsigned dtype; 35 | 36 | static Mtrr * list; 37 | static Slab_cache cache; 38 | 39 | uint64 size() const 40 | { 41 | return 1ULL << (static_cast(mask) ? bit_scan_forward (static_cast(mask >> 12)) + 12 : 42 | bit_scan_forward (static_cast(mask >> 32)) + 32); 43 | } 44 | 45 | public: 46 | ALWAYS_INLINE 47 | explicit inline Mtrr (uint64 b, uint64 m) : List (list), base (b), mask (m) {} 48 | 49 | ALWAYS_INLINE 50 | static inline void *operator new (size_t) { return cache.alloc(); } 51 | 52 | INIT 53 | static void init(); 54 | 55 | INIT 56 | static unsigned memtype (uint64, uint64 &); 57 | }; 58 | -------------------------------------------------------------------------------- /include/multiboot.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Multiboot Support 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | 23 | /* 24 | * Multiboot Information Structure 25 | */ 26 | class Multiboot 27 | { 28 | public: 29 | enum 30 | { 31 | MAGIC = 0x2badb002, 32 | MEMORY = 1ul << 0, 33 | BOOT_DEVICE = 1ul << 1, 34 | CMDLINE = 1ul << 2, 35 | MODULES = 1ul << 3, 36 | SYMBOLS = 1ul << 4 | 1ul << 5, 37 | MEMORY_MAP = 1ul << 6, 38 | DRIVES = 1ul << 7, 39 | CONFIG_TABLE = 1ul << 8, 40 | LOADER_NAME = 1ul << 9, 41 | APM_TABLE = 1ul << 10, 42 | VBE_INFO = 1ul << 11 43 | }; 44 | 45 | uint32 flags; // 0 46 | uint32 mem_lower; // 4 47 | uint32 mem_upper; // 8 48 | uint32 boot_device; // 12 49 | uint32 cmdline; // 16 50 | uint32 mods_count; // 20 51 | uint32 mods_addr; // 24 52 | uint32 syms[4]; // 28,32,36,40 53 | uint32 mmap_len; // 44 54 | uint32 mmap_addr; // 48 55 | uint32 drives_length; // 52 56 | uint32 drives_addr; // 56 57 | uint32 config_table; // 60 58 | uint32 loader_name; // 64 59 | }; 60 | 61 | /* 62 | * Multiboot Module 63 | */ 64 | class Multiboot_module 65 | { 66 | public: 67 | uint32 s_addr; 68 | uint32 e_addr; 69 | uint32 cmdline; 70 | uint32 reserved; 71 | }; 72 | 73 | /* 74 | * Multiboot Memory Map 75 | */ 76 | #pragma pack(1) 77 | class Multiboot_mmap 78 | { 79 | public: 80 | uint32 size; 81 | uint64 addr; 82 | uint64 len; 83 | uint32 type; 84 | }; 85 | #pragma pack() 86 | -------------------------------------------------------------------------------- /include/pd.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Protection Domain 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "crd.hpp" 24 | #include "space_mem.hpp" 25 | #include "space_obj.hpp" 26 | #include "space_pio.hpp" 27 | 28 | class Pd : public Kobject, public Refcount, public Space_mem, public Space_pio, public Space_obj 29 | { 30 | private: 31 | static Slab_cache cache; 32 | 33 | WARN_UNUSED_RESULT 34 | mword clamp (mword, mword &, mword, mword); 35 | 36 | WARN_UNUSED_RESULT 37 | mword clamp (mword &, mword &, mword, mword, mword); 38 | 39 | public: 40 | static Pd *current CPULOCAL_HOT; 41 | static Pd kern, root; 42 | 43 | INIT 44 | Pd (Pd *); 45 | 46 | Pd (Pd *own, mword sel, mword a) : Kobject (PD, static_cast(own), sel, a) {} 47 | 48 | ALWAYS_INLINE HOT 49 | inline void make_current() 50 | { 51 | if (EXPECT_FALSE (htlb.chk (Cpu::id))) 52 | htlb.clr (Cpu::id); 53 | 54 | else if (EXPECT_TRUE (current == this)) 55 | return; 56 | 57 | current = this; 58 | 59 | loc[Cpu::id].make_current(); 60 | } 61 | 62 | ALWAYS_INLINE 63 | static inline Pd *remote (unsigned c) 64 | { 65 | return *reinterpret_cast(reinterpret_cast(¤t) - CPU_LOCAL_DATA + HV_GLOBAL_CPUS + c * PAGE_SIZE); 66 | } 67 | 68 | ALWAYS_INLINE 69 | inline Space *subspace (Crd::Type t) 70 | { 71 | switch (t) { 72 | case Crd::MEM: return static_cast(this); 73 | case Crd::PIO: return static_cast(this); 74 | case Crd::OBJ: return static_cast(this); 75 | } 76 | 77 | return nullptr; 78 | } 79 | 80 | template 81 | void delegate (Pd *, mword, mword, mword, mword, mword = 0); 82 | 83 | template 84 | void revoke (mword, mword, mword, bool); 85 | 86 | void xfer_items (Pd *, Crd, Crd, Xfer *, Xfer *, unsigned long); 87 | 88 | void xlt_crd (Pd *, Crd, Crd &); 89 | void del_crd (Pd *, Crd, Crd &, mword = 0, mword = 0); 90 | void rev_crd (Crd, bool); 91 | 92 | ALWAYS_INLINE 93 | static inline void *operator new (size_t) { return cache.alloc(); } 94 | 95 | ALWAYS_INLINE 96 | static inline void operator delete (void *ptr) { cache.free (ptr); } 97 | }; 98 | -------------------------------------------------------------------------------- /include/pt.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Portal 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "kobject.hpp" 24 | #include "mtd.hpp" 25 | 26 | class Ec; 27 | 28 | class Pt : public Kobject 29 | { 30 | private: 31 | static Slab_cache cache; 32 | 33 | public: 34 | Refptr const ec; 35 | Mtd const mtd; 36 | mword const ip; 37 | mword id; 38 | 39 | Pt (Pd *, mword, Ec *, Mtd, mword); 40 | 41 | ALWAYS_INLINE 42 | inline void set_id (mword i) { id = i; } 43 | 44 | ALWAYS_INLINE 45 | static inline void *operator new (size_t) { return cache.alloc(); } 46 | 47 | ALWAYS_INLINE 48 | static inline void operator delete (void *ptr) { cache.free (ptr); } 49 | }; 50 | -------------------------------------------------------------------------------- /include/pte.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Page Table Entry (PTE) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "atomic.hpp" 24 | #include "buddy.hpp" 25 | #include "x86.hpp" 26 | 27 | template 28 | class Pte 29 | { 30 | protected: 31 | E val; 32 | 33 | P *walk (E, unsigned long, bool = true); 34 | 35 | ALWAYS_INLINE 36 | inline bool present() const { return val & P::PTE_P; } 37 | 38 | ALWAYS_INLINE 39 | inline bool super() const { return val & P::PTE_S; } 40 | 41 | ALWAYS_INLINE 42 | inline mword attr() const { return static_cast(val) & PAGE_MASK; } 43 | 44 | ALWAYS_INLINE 45 | inline Paddr addr() const { return static_cast(val) & ~((1UL << order()) - 1); } 46 | 47 | ALWAYS_INLINE 48 | inline mword order() const { return PAGE_BITS; } 49 | 50 | ALWAYS_INLINE 51 | static inline mword order (mword) { return 0; } 52 | 53 | ALWAYS_INLINE 54 | inline bool set (E o, E v) 55 | { 56 | bool b = Atomic::cmp_swap (val, o, v); 57 | 58 | if (F && b) 59 | flush (this); 60 | 61 | return b; 62 | } 63 | 64 | ALWAYS_INLINE 65 | static inline void *operator new (size_t) 66 | { 67 | void *p = Buddy::allocator.alloc (0, Buddy::FILL_0); 68 | 69 | if (F) 70 | flush (p, PAGE_SIZE); 71 | 72 | return p; 73 | } 74 | 75 | ALWAYS_INLINE 76 | static inline void operator delete (void *ptr) { Buddy::allocator.free (reinterpret_cast(ptr)); } 77 | 78 | public: 79 | enum 80 | { 81 | ERR_P = 1UL << 0, 82 | ERR_W = 1UL << 1, 83 | ERR_U = 1UL << 2, 84 | }; 85 | 86 | enum Type 87 | { 88 | TYPE_UP, 89 | TYPE_DN, 90 | TYPE_DF, 91 | }; 92 | 93 | ALWAYS_INLINE 94 | static inline unsigned bpl() { return B; } 95 | 96 | ALWAYS_INLINE 97 | static inline unsigned max() { return L; } 98 | 99 | ALWAYS_INLINE 100 | inline E root (mword l = L - 1) { return Buddy::ptr_to_phys (walk (0, l)); } 101 | 102 | size_t lookup (E, Paddr &, mword &); 103 | 104 | void update (E, mword, E, mword, Type = TYPE_UP); 105 | }; 106 | -------------------------------------------------------------------------------- /include/qpd.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Quantum Priority Descriptor (QPD) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | 23 | class Qpd 24 | { 25 | private: 26 | mword val; 27 | 28 | public: 29 | ALWAYS_INLINE 30 | inline explicit Qpd (mword v) : val (v) {} 31 | 32 | ALWAYS_INLINE 33 | inline unsigned quantum() const 34 | { 35 | return static_cast(val >> 12); 36 | } 37 | 38 | ALWAYS_INLINE 39 | inline unsigned prio() const 40 | { 41 | return static_cast(val & 0xff); 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /include/queue.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Queue 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | 23 | template 24 | class Queue 25 | { 26 | private: 27 | T *queue; 28 | 29 | public: 30 | ALWAYS_INLINE 31 | inline Queue() : queue (nullptr) {} 32 | 33 | ALWAYS_INLINE 34 | inline T *head() const { return queue; } 35 | 36 | ALWAYS_INLINE 37 | inline void enqueue (T *t) 38 | { 39 | if (!queue) 40 | queue = t->prev = t->next = t; 41 | else { 42 | t->next = queue; 43 | t->prev = queue->prev; 44 | t->next->prev = t->prev->next = t; 45 | } 46 | } 47 | 48 | ALWAYS_INLINE 49 | inline T *dequeue() 50 | { 51 | T *t = queue; 52 | 53 | if (!t) 54 | return nullptr; 55 | 56 | if (t == t->next) 57 | queue = nullptr; 58 | else { 59 | queue = t->next; 60 | t->next->prev = t->prev; 61 | t->prev->next = t->next; 62 | } 63 | 64 | t->next = t->prev = nullptr; 65 | 66 | return t; 67 | } 68 | }; 69 | -------------------------------------------------------------------------------- /include/rcu.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Read-Copy Update (RCU) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | #include "types.hpp" 23 | 24 | class Rcu_elem 25 | { 26 | public: 27 | Rcu_elem *next; 28 | void (*func)(Rcu_elem *); 29 | 30 | ALWAYS_INLINE 31 | explicit Rcu_elem (void (*f)(Rcu_elem *)) : next (nullptr), func (f) {} 32 | }; 33 | 34 | class Rcu_list 35 | { 36 | public: 37 | Rcu_elem * head; 38 | Rcu_elem ** tail; 39 | 40 | ALWAYS_INLINE 41 | explicit Rcu_list() { clear(); } 42 | 43 | ALWAYS_INLINE 44 | inline void clear() { head = nullptr; tail = &head; } 45 | 46 | ALWAYS_INLINE 47 | inline void append (Rcu_list *l) 48 | { 49 | *tail = l->head; 50 | tail = l->tail; 51 | l->clear(); 52 | } 53 | 54 | ALWAYS_INLINE 55 | inline void enqueue (Rcu_elem *e) 56 | { 57 | e->next = nullptr; 58 | *tail = e; 59 | tail = &e->next; 60 | } 61 | }; 62 | 63 | class Rcu 64 | { 65 | private: 66 | static mword count; 67 | static mword state; 68 | 69 | static mword l_batch CPULOCAL; 70 | static mword c_batch CPULOCAL; 71 | 72 | static Rcu_list next CPULOCAL; 73 | static Rcu_list curr CPULOCAL; 74 | static Rcu_list done CPULOCAL; 75 | 76 | enum State 77 | { 78 | RCU_CMP = 1UL << 0, 79 | RCU_PND = 1UL << 1, 80 | }; 81 | 82 | ALWAYS_INLINE 83 | static inline mword batch() { return state >> 2; } 84 | 85 | ALWAYS_INLINE 86 | static inline bool complete (mword b) { return static_cast((state & ~RCU_PND) - (b << 2)) > 0; } 87 | 88 | static void start_batch (State); 89 | static void invoke_batch(); 90 | 91 | public: 92 | ALWAYS_INLINE 93 | static inline void call (Rcu_elem *e) { next.enqueue (e); } 94 | 95 | static void quiet(); 96 | static void update(); 97 | }; 98 | -------------------------------------------------------------------------------- /include/refptr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Reference-Counted Pointer 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "atomic.hpp" 24 | 25 | class Refcount 26 | { 27 | private: 28 | uint32 ref; 29 | 30 | public: 31 | ALWAYS_INLINE 32 | inline Refcount() : ref (1) {} 33 | 34 | ALWAYS_INLINE 35 | inline bool add_ref() 36 | { 37 | for (uint32 r; (r = ref); ) 38 | if (Atomic::cmp_swap (ref, r, r + 1)) 39 | return true; 40 | 41 | return false; 42 | } 43 | 44 | ALWAYS_INLINE 45 | inline bool del_ref() 46 | { 47 | return Atomic::sub (ref, 1U) == 0; 48 | } 49 | }; 50 | 51 | template 52 | class Refptr 53 | { 54 | private: 55 | T * const ptr; 56 | 57 | public: 58 | operator T*() const { return ptr; } 59 | T * operator->() const { return ptr; } 60 | 61 | ALWAYS_INLINE 62 | inline Refptr (T *p) : ptr (p->add_ref() ? p : nullptr) {} 63 | 64 | ALWAYS_INLINE 65 | inline ~Refptr() 66 | { 67 | if (ptr->del_ref()) 68 | delete ptr; 69 | } 70 | }; 71 | -------------------------------------------------------------------------------- /include/sc.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Scheduling Context 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "compiler.hpp" 24 | 25 | class Ec; 26 | 27 | class Sc : public Kobject 28 | { 29 | friend class Queue; 30 | 31 | public: 32 | Refptr const ec; 33 | unsigned const cpu; 34 | unsigned const prio; 35 | unsigned const budget; 36 | uint64 time; 37 | 38 | private: 39 | unsigned left; 40 | Sc *prev, *next; 41 | uint64 tsc; 42 | 43 | static unsigned const priorities = 128; 44 | 45 | static Slab_cache cache; 46 | 47 | static struct Rq { 48 | Spinlock lock; 49 | Sc * queue; 50 | } rq CPULOCAL; 51 | 52 | static Sc *list[priorities] CPULOCAL; 53 | 54 | static unsigned prio_top CPULOCAL; 55 | 56 | void ready_enqueue (uint64); 57 | void ready_dequeue (uint64); 58 | 59 | public: 60 | static Sc * current CPULOCAL_HOT; 61 | static unsigned ctr_link CPULOCAL; 62 | static unsigned ctr_loop CPULOCAL; 63 | 64 | static unsigned const default_prio = 1; 65 | static unsigned const default_quantum = 10000; 66 | 67 | Sc (Pd *, mword, Ec *); 68 | Sc (Pd *, mword, Ec *, unsigned, unsigned, unsigned); 69 | 70 | ALWAYS_INLINE 71 | static inline Rq *remote (unsigned long c) 72 | { 73 | return reinterpret_cast(reinterpret_cast(&rq) - CPU_LOCAL_DATA + HV_GLOBAL_CPUS + c * PAGE_SIZE); 74 | } 75 | 76 | void remote_enqueue(); 77 | 78 | static void rrq_handler(); 79 | static void rke_handler(); 80 | 81 | NORETURN 82 | static void schedule (bool = false); 83 | 84 | ALWAYS_INLINE 85 | static inline void *operator new (size_t) { return cache.alloc(); } 86 | 87 | ALWAYS_INLINE 88 | static inline void operator delete (void *ptr) { cache.free (ptr); } 89 | }; 90 | -------------------------------------------------------------------------------- /include/selectors.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Selectors 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #define SEL_NULL_DESC 0x0 24 | #define SEL_KERN_CODE 0x8 25 | #define SEL_KERN_DATA 0x10 26 | #define SEL_USER_CODE 0x1b 27 | #define SEL_USER_DATA 0x23 28 | #define SEL_USER_CODE_L 0x2b 29 | #define SEL_TSS_RUN 0x30 30 | #define SEL_TSS_DBF 0x40 31 | #define SEL_MAX 0x50 32 | -------------------------------------------------------------------------------- /include/slab.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Slab Allocator 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "buddy.hpp" 24 | #include "initprio.hpp" 25 | 26 | class Slab; 27 | 28 | class Slab_cache 29 | { 30 | private: 31 | Spinlock lock; 32 | Slab * curr; 33 | Slab * head; 34 | 35 | /* 36 | * Back end allocator 37 | */ 38 | void grow(); 39 | 40 | public: 41 | unsigned long size; // Size of an element 42 | unsigned long buff; // Size of an element buffer (includes link field) 43 | unsigned long elem; // Number of elements 44 | 45 | Slab_cache (unsigned long elem_size, unsigned elem_align); 46 | 47 | /* 48 | * Front end allocator 49 | */ 50 | void *alloc(); 51 | 52 | /* 53 | * Front end deallocator 54 | */ 55 | void free (void *ptr); 56 | }; 57 | 58 | class Slab 59 | { 60 | public: 61 | unsigned long avail; 62 | Slab_cache * cache; 63 | Slab * prev; // Prev slab in cache 64 | Slab * next; // Next slab in cache 65 | char * head; 66 | 67 | ALWAYS_INLINE 68 | static inline void *operator new (size_t) 69 | { 70 | return Buddy::allocator.alloc (0, Buddy::FILL_0); 71 | } 72 | 73 | ALWAYS_INLINE 74 | static inline void operator delete (void *ptr) 75 | { 76 | Buddy::allocator.free (reinterpret_cast(ptr)); 77 | } 78 | 79 | Slab (Slab_cache *slab_cache); 80 | 81 | ALWAYS_INLINE 82 | inline bool full() const 83 | { 84 | return !avail; 85 | } 86 | 87 | ALWAYS_INLINE 88 | inline bool empty() const 89 | { 90 | return avail == cache->elem; 91 | } 92 | 93 | void enqueue(); 94 | void dequeue(); 95 | 96 | ALWAYS_INLINE 97 | inline void *alloc(); 98 | 99 | ALWAYS_INLINE 100 | inline void free (void *ptr); 101 | }; 102 | -------------------------------------------------------------------------------- /include/sm.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Semaphore 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "ec.hpp" 24 | 25 | class Sm : public Kobject, public Queue 26 | { 27 | private: 28 | mword counter; 29 | 30 | static Slab_cache cache; 31 | 32 | public: 33 | Sm (Pd *, mword, mword = 0); 34 | 35 | ALWAYS_INLINE 36 | inline void dn (bool zero) 37 | { 38 | Ec *e = Ec::current; 39 | 40 | { Lock_guard guard (lock); 41 | 42 | if (counter) { 43 | counter = zero ? 0 : counter - 1; 44 | return; 45 | } 46 | 47 | enqueue (e); 48 | } 49 | 50 | e->block_sc(); 51 | } 52 | 53 | ALWAYS_INLINE 54 | inline void up() 55 | { 56 | Ec *e; 57 | 58 | { Lock_guard guard (lock); 59 | 60 | if (!(e = dequeue())) { 61 | counter++; 62 | return; 63 | } 64 | } 65 | 66 | e->release(); 67 | } 68 | 69 | ALWAYS_INLINE 70 | static inline void *operator new (size_t) { return cache.alloc(); } 71 | 72 | ALWAYS_INLINE 73 | static inline void operator delete (void *ptr) { cache.free (ptr); } 74 | }; 75 | -------------------------------------------------------------------------------- /include/space.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic Space 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "bits.hpp" 24 | #include "lock_guard.hpp" 25 | #include "mdb.hpp" 26 | 27 | class Space 28 | { 29 | private: 30 | Spinlock lock; 31 | Avl * tree; 32 | 33 | public: 34 | Space() : tree (nullptr) {} 35 | 36 | Mdb *tree_lookup (mword idx, bool next = false) 37 | { 38 | Lock_guard guard (lock); 39 | return Mdb::lookup (tree, idx, next); 40 | } 41 | 42 | static bool tree_insert (Mdb *node) 43 | { 44 | Lock_guard guard (node->space->lock); 45 | return Mdb::insert (&node->space->tree, node); 46 | } 47 | 48 | static bool tree_remove (Mdb *node) 49 | { 50 | Lock_guard guard (node->space->lock); 51 | return Mdb::remove (&node->space->tree, node); 52 | } 53 | 54 | void addreg (mword addr, size_t size, mword attr, mword type = 0) 55 | { 56 | Lock_guard guard (lock); 57 | 58 | for (mword o; size; size -= 1UL << o, addr += 1UL << o) 59 | Mdb::insert (&tree, new Mdb (nullptr, addr, addr, (o = max_order (addr, size)), attr, type)); 60 | } 61 | 62 | void delreg (mword addr) 63 | { 64 | Mdb *node; 65 | 66 | { Lock_guard guard (lock); 67 | 68 | if (!(node = Mdb::lookup (tree, addr >>= PAGE_BITS, false))) 69 | return; 70 | 71 | Mdb::remove (&tree, node); 72 | } 73 | 74 | mword next = addr + 1, base = node->node_base, last = base + (1UL << node->node_order); 75 | 76 | addreg (base, addr - base, node->node_attr, node->node_type); 77 | addreg (next, last - next, node->node_attr, node->node_type); 78 | 79 | delete node; 80 | } 81 | }; 82 | -------------------------------------------------------------------------------- /include/space_mem.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Memory Space 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "config.hpp" 24 | #include "cpu.hpp" 25 | #include "cpuset.hpp" 26 | #include "dpt.hpp" 27 | #include "ept.hpp" 28 | #include "hpt.hpp" 29 | #include "space.hpp" 30 | 31 | class Space_mem : public Space 32 | { 33 | public: 34 | Hpt loc[NUM_CPU]; 35 | Hpt hpt; 36 | Dpt dpt; 37 | union { 38 | Ept ept; 39 | Hpt npt; 40 | }; 41 | 42 | mword did; 43 | 44 | Cpuset cpus; 45 | Cpuset htlb; 46 | Cpuset gtlb; 47 | 48 | static unsigned did_ctr; 49 | 50 | ALWAYS_INLINE 51 | inline size_t lookup (mword virt, Paddr &phys) 52 | { 53 | mword attr; 54 | return hpt.lookup (virt, phys, attr); 55 | } 56 | 57 | ALWAYS_INLINE 58 | inline void insert (mword virt, unsigned o, mword attr, Paddr phys) 59 | { 60 | hpt.update (virt, o, phys, attr); 61 | } 62 | 63 | ALWAYS_INLINE 64 | inline Paddr replace (mword v, Paddr p) 65 | { 66 | return hpt.replace (v, p); 67 | } 68 | 69 | INIT 70 | void insert_root (uint64, uint64, mword = 0x7); 71 | 72 | bool insert_utcb (mword); 73 | 74 | void update (Mdb *, mword = 0); 75 | 76 | static void shootdown(); 77 | 78 | void init (unsigned); 79 | }; 80 | -------------------------------------------------------------------------------- /include/space_obj.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Object Space 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "capability.hpp" 24 | #include "space.hpp" 25 | 26 | class Space_mem; 27 | 28 | class Space_obj : public Space 29 | { 30 | private: 31 | ALWAYS_INLINE 32 | static inline mword idx_to_virt (unsigned long idx) 33 | { 34 | return SPC_LOCAL_OBJ + (idx % caps) * sizeof (Capability); 35 | } 36 | 37 | ALWAYS_INLINE 38 | inline Space_mem *space_mem(); 39 | 40 | void update (mword, Capability); 41 | 42 | public: 43 | static unsigned const caps = (END_SPACE_LIM - SPC_LOCAL_OBJ) / sizeof (Capability); 44 | 45 | ALWAYS_INLINE 46 | static inline Capability lookup (unsigned long idx) 47 | { 48 | return *reinterpret_cast(idx_to_virt (idx)); 49 | } 50 | 51 | size_t lookup (mword, Capability &); 52 | 53 | Paddr walk (mword = 0); 54 | 55 | void update (Mdb *, mword = 0); 56 | 57 | static void page_fault (mword, mword); 58 | 59 | static bool insert_root (Kobject *); 60 | }; 61 | -------------------------------------------------------------------------------- /include/space_pio.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Port I/O Space 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "space.hpp" 24 | 25 | class Space_mem; 26 | 27 | class Space_pio : public Space 28 | { 29 | private: 30 | Paddr hbmp, gbmp; 31 | 32 | ALWAYS_INLINE 33 | static inline mword idx_to_virt (mword idx) 34 | { 35 | return SPC_LOCAL_IOP + (idx / 8 / sizeof (mword)) * sizeof (mword); 36 | } 37 | 38 | ALWAYS_INLINE 39 | static inline mword idx_to_mask (mword idx) 40 | { 41 | return 1UL << (idx % (8 * sizeof (mword))); 42 | } 43 | 44 | ALWAYS_INLINE 45 | inline Space_mem *space_mem(); 46 | 47 | void update (bool, mword, mword); 48 | 49 | public: 50 | Paddr walk (bool = false, mword = 0); 51 | 52 | void update (Mdb *, mword = 0); 53 | 54 | static void page_fault (mword, mword); 55 | }; 56 | -------------------------------------------------------------------------------- /include/spinlock.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic Spinlock 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | #include "types.hpp" 23 | 24 | class Spinlock 25 | { 26 | private: 27 | uint16 val; 28 | 29 | public: 30 | ALWAYS_INLINE 31 | inline Spinlock() : val (0) {} 32 | 33 | NOINLINE 34 | void lock() 35 | { 36 | uint16 tmp = 0x100; 37 | 38 | asm volatile (" lock; xadd %0, %1; " 39 | "1: cmpb %h0, %b0; " 40 | " je 2f; " 41 | " pause; " 42 | " movb %1, %b0; " 43 | " jmp 1b; " 44 | "2: " 45 | : "+Q" (tmp), "+m" (val) : : "memory"); 46 | } 47 | 48 | ALWAYS_INLINE 49 | inline void unlock() 50 | { 51 | asm volatile ("incb %0" : "=m" (val) : : "memory"); 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /include/stdio.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Standard I/O 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "console.hpp" 24 | #include "cpu.hpp" 25 | #include "memory.hpp" 26 | 27 | #define trace(T,format,...) \ 28 | do { \ 29 | register mword __esp asm ("esp"); \ 30 | if (EXPECT_FALSE ((trace_mask & (T)) == (T))) \ 31 | Console::print ("[%2ld] " format, \ 32 | ((__esp - 1) & ~PAGE_MASK) == CPU_LOCAL_STCK ? \ 33 | Cpu::id : ~0UL, ## __VA_ARGS__); \ 34 | } while (0) 35 | 36 | /* 37 | * Definition of trace events 38 | */ 39 | enum { 40 | TRACE_CPU = 1UL << 0, 41 | TRACE_IOMMU = 1UL << 1, 42 | TRACE_APIC = 1UL << 2, 43 | TRACE_KEYB = 1UL << 3, 44 | TRACE_VMX = 1UL << 4, 45 | TRACE_SVM = 1UL << 5, 46 | TRACE_ACPI = 1UL << 8, 47 | TRACE_MEMORY = 1UL << 13, 48 | TRACE_PCI = 1UL << 14, 49 | TRACE_SCHEDULE = 1UL << 16, 50 | TRACE_VTLB = 1UL << 17, 51 | TRACE_DEL = 1UL << 18, 52 | TRACE_REV = 1UL << 19, 53 | TRACE_RCU = 1UL << 20, 54 | TRACE_FPU = 1UL << 23, 55 | TRACE_SYSCALL = 1UL << 30, 56 | TRACE_ERROR = 1UL << 31, 57 | }; 58 | 59 | /* 60 | * Enabled trace events 61 | */ 62 | unsigned const trace_mask = 63 | TRACE_CPU | 64 | TRACE_IOMMU | 65 | #ifdef DEBUG 66 | // TRACE_APIC | 67 | // TRACE_KEYB | 68 | TRACE_VMX | 69 | TRACE_SVM | 70 | // TRACE_ACPI | 71 | // TRACE_MEMORY | 72 | // TRACE_PCI | 73 | // TRACE_SCHEDULE | 74 | // TRACE_VTLB | 75 | // TRACE_DEL | 76 | // TRACE_REV | 77 | // TRACE_RCU | 78 | // TRACE_FPU | 79 | // TRACE_SYSCALL | 80 | TRACE_ERROR | 81 | #endif 82 | 0; 83 | -------------------------------------------------------------------------------- /include/string.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * String Functions 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | #include "types.hpp" 23 | 24 | extern "C" NONNULL 25 | inline void *memcpy (void *d, void const *s, size_t n) 26 | { 27 | mword dummy; 28 | asm volatile ("rep; movsb" 29 | : "=D" (dummy), "+S" (s), "+c" (n) 30 | : "0" (d) 31 | : "memory"); 32 | return d; 33 | } 34 | 35 | extern "C" NONNULL 36 | inline void *memset (void *d, int c, size_t n) 37 | { 38 | mword dummy; 39 | asm volatile ("rep; stosb" 40 | : "=D" (dummy), "+c" (n) 41 | : "0" (d), "a" (c) 42 | : "memory"); 43 | return d; 44 | } 45 | 46 | extern "C" NONNULL 47 | inline int strcmp (char const *s1, char const *s2) 48 | { 49 | while (*s1 && *s1 == *s2) 50 | s1++, s2++; 51 | 52 | return *s1 - *s2; 53 | } 54 | -------------------------------------------------------------------------------- /include/tss.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Task State Segment (TSS) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "compiler.hpp" 24 | #include "selectors.hpp" 25 | 26 | class Tss 27 | { 28 | public: 29 | uint32 : 32; // 0x0 30 | 31 | #ifdef __i386__ 32 | uint32 sp0; // 0x4 33 | uint16 ss0; uint16 : 16; // 0x8 34 | uint32 sp1; // 0xc 35 | uint16 ss1; uint16 : 16; // 0x10 36 | uint32 sp2; // 0x14 37 | uint16 ss2; uint16 : 16; // 0x18 38 | uint32 cr3; // 0x1c 39 | uint32 eip; // 0x20 40 | uint32 eflags; // 0x24 41 | uint32 eax; // 0x28 42 | uint32 ecx; // 0x2c 43 | uint32 edx; // 0x30 44 | uint32 ebx; // 0x34 45 | uint32 esp; // 0x38 46 | uint32 ebp; // 0x3c 47 | uint32 esi; // 0x40 48 | uint32 edi; // 0x44 49 | uint16 es; uint16 : 16; // 0x48 50 | uint16 cs; uint16 : 16; // 0x4c 51 | uint16 ss; uint16 : 16; // 0x50 52 | uint16 ds; uint16 : 16; // 0x54 53 | uint16 fs; uint16 : 16; // 0x58 54 | uint16 gs; uint16 : 16; // 0x5c 55 | uint16 ldt; uint16 : 16; // 0x60 56 | #endif 57 | 58 | #ifdef __x86_64__ 59 | uint64 sp0 PACKED; // 0x4 60 | uint64 sp1 PACKED; // 0xc 61 | uint64 sp2 PACKED; // 0x14 62 | uint64 ist[8] PACKED; // 0x1c 63 | uint64 : 64 PACKED; 64 | #endif 65 | 66 | uint16 trap; // 0x64 67 | uint16 iobm; // 0x66 68 | 69 | static Tss run asm ("tss_run") CPULOCAL; 70 | static Tss dbf asm ("tss_dbf") CPULOCAL; 71 | 72 | static void build(); 73 | 74 | ALWAYS_INLINE 75 | static inline void load() 76 | { 77 | asm volatile ("ltr %w0" : : "rm" (SEL_TSS_RUN)); 78 | } 79 | }; 80 | -------------------------------------------------------------------------------- /include/types.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Constant-Width Types 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | typedef unsigned char uint8; 24 | typedef unsigned short uint16; 25 | typedef unsigned int uint32; 26 | typedef unsigned long long uint64; 27 | 28 | typedef unsigned long mword; 29 | typedef unsigned long Paddr; 30 | -------------------------------------------------------------------------------- /include/user.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * User Memory Access 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "arch.hpp" 24 | #include "compiler.hpp" 25 | 26 | class User 27 | { 28 | public: 29 | template 30 | ALWAYS_INLINE 31 | static inline mword peek (T *addr, T &val) 32 | { 33 | mword ret; 34 | asm volatile ("1: mov %2, %1; or $-1, %0; 2:" 35 | ".section .fixup,\"a\"; .align 8;" EXPAND (WORD) " 1b,2b; .previous" 36 | : "=a" (ret), "=q" (val) : "m" (*addr)); 37 | return ret; 38 | } 39 | 40 | template 41 | ALWAYS_INLINE 42 | static inline mword cmp_swap (T *addr, T o, T n) 43 | { 44 | mword ret; 45 | asm volatile ("1: lock; cmpxchg %3, %1; or $-1, %0; 2:" 46 | ".section .fixup,\"a\"; .align 8;" EXPAND (WORD) " 1b,2b; .previous" 47 | : "=a" (ret), "+m" (*addr) : "a" (o), "q" (n)); 48 | return ret; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /include/util.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Utility Functions 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | 23 | template 24 | ALWAYS_INLINE 25 | static inline T min (T v1, T v2) 26 | { 27 | return v1 < v2 ? v1 : v2; 28 | } 29 | 30 | template 31 | ALWAYS_INLINE 32 | static inline T max (T v1, T v2) 33 | { 34 | return v1 > v2 ? v1 : v2; 35 | } 36 | -------------------------------------------------------------------------------- /include/vectors.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Interrupt Vectors 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "config.hpp" 22 | 23 | #define VEC_GSI (NUM_EXC) 24 | #define VEC_LVT (VEC_GSI + NUM_GSI) 25 | #define VEC_MSI (VEC_LVT + NUM_LVT) 26 | #define VEC_IPI (VEC_MSI + NUM_MSI) 27 | #define VEC_MAX (VEC_IPI + NUM_IPI) 28 | 29 | #define VEC_LVT_TIMER (VEC_LVT + 0) 30 | #define VEC_LVT_ERROR (VEC_LVT + 3) 31 | #define VEC_LVT_PERFM (VEC_LVT + 4) 32 | #define VEC_LVT_THERM (VEC_LVT + 5) 33 | 34 | #define VEC_MSI_DMAR (VEC_MSI + 0) 35 | 36 | #define VEC_IPI_RRQ (VEC_IPI + 0) 37 | #define VEC_IPI_RKE (VEC_IPI + 1) 38 | -------------------------------------------------------------------------------- /include/vpid.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Virtual Processor Identifier (VPID) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #pragma once 20 | 21 | #include "compiler.hpp" 22 | 23 | class Invvpid 24 | { 25 | private: 26 | uint64 vpid; 27 | uint64 addr; 28 | 29 | public: 30 | ALWAYS_INLINE 31 | inline Invvpid (unsigned long v, mword a) : vpid (v), addr (a) {} 32 | }; 33 | 34 | class Vpid 35 | { 36 | public: 37 | enum Type 38 | { 39 | ADDRESS = 0, 40 | CONTEXT_GLOBAL = 1, 41 | CONTEXT_NOGLOBAL = 3 42 | }; 43 | 44 | ALWAYS_INLINE 45 | static inline void flush (Type t, unsigned long vpid, mword addr = 0) 46 | { 47 | asm volatile ("invvpid %0, %1" : : "m" (Invvpid (vpid, addr)), "r" (static_cast(t)) : "cc"); 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /include/vtlb.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Virtual Translation Lookaside Buffer (VTLB) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "pte.hpp" 24 | #include "user.hpp" 25 | 26 | class Exc_regs; 27 | 28 | #ifdef __i386__ 29 | class Vtlb : public Pte 30 | #else 31 | class Vtlb : public Pte 32 | #endif 33 | { 34 | private: 35 | ALWAYS_INLINE 36 | inline bool mark() const { return val & TLB_M; } 37 | 38 | ALWAYS_INLINE 39 | inline bool frag() const { return val & TLB_F; } 40 | 41 | ALWAYS_INLINE 42 | static inline bool mark_pte (uint32 *pte, uint32 old, uint32 bits) 43 | { 44 | return EXPECT_TRUE ((old & bits) == bits) || User::cmp_swap (pte, old, old | bits) == ~0UL; 45 | } 46 | 47 | void flush_ptab (bool); 48 | 49 | public: 50 | static size_t gwalk (Exc_regs *, mword, mword &, mword &, mword &); 51 | static size_t hwalk (mword, mword &, mword &, mword &); 52 | 53 | enum 54 | { 55 | TLB_P = 1UL << 0, 56 | TLB_W = 1UL << 1, 57 | TLB_U = 1UL << 2, 58 | TLB_UC = 1UL << 4, 59 | TLB_A = 1UL << 5, 60 | TLB_D = 1UL << 6, 61 | TLB_S = 1UL << 7, 62 | TLB_G = 1UL << 8, 63 | TLB_F = 1UL << 9, 64 | TLB_M = 1UL << 10, 65 | 66 | PTE_P = TLB_P, 67 | PTE_S = TLB_S, 68 | }; 69 | 70 | enum Reason 71 | { 72 | SUCCESS, 73 | GLA_GPA, 74 | GPA_HPA, 75 | FAILURE, 76 | }; 77 | 78 | ALWAYS_INLINE 79 | inline Vtlb() 80 | { 81 | for (unsigned i = 0; i < 1UL << bpl(); i++) 82 | this[i].val = TLB_S; 83 | } 84 | 85 | void flush (mword); 86 | void flush (bool); 87 | 88 | static Reason miss (Exc_regs *, mword, mword &); 89 | 90 | ALWAYS_INLINE 91 | static inline void *operator new (size_t) { return Buddy::allocator.alloc (0, Buddy::NOFILL); } 92 | }; 93 | -------------------------------------------------------------------------------- /include/x86.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * x86-Specific Functions 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "compiler.hpp" 24 | 25 | template 26 | ALWAYS_INLINE 27 | static inline void flush (T t) 28 | { 29 | asm volatile ("clflush %0" : : "m" (*t) : "memory"); 30 | } 31 | 32 | ALWAYS_INLINE NONNULL 33 | inline void *flush (void *d, size_t n) 34 | { 35 | for (char *p = static_cast(d); p < static_cast(d) + n; p += 32) 36 | flush (p); 37 | 38 | return d; 39 | } 40 | 41 | ALWAYS_INLINE NORETURN 42 | inline void shutdown() 43 | { 44 | for (;;) 45 | asm volatile ("cli; hlt"); 46 | } 47 | 48 | ALWAYS_INLINE 49 | static inline void wbinvd() 50 | { 51 | asm volatile ("wbinvd" : : : "memory"); 52 | } 53 | 54 | ALWAYS_INLINE 55 | static inline void pause() 56 | { 57 | asm volatile ("pause" : : : "memory"); 58 | } 59 | 60 | ALWAYS_INLINE 61 | static inline uint64 rdtsc() 62 | { 63 | mword h, l; 64 | asm volatile ("rdtsc" : "=a" (l), "=d" (h)); 65 | return static_cast(h) << 32 | l; 66 | } 67 | 68 | ALWAYS_INLINE 69 | static inline mword get_cr0() 70 | { 71 | mword cr0; 72 | asm volatile ("mov %%cr0, %0" : "=r" (cr0)); 73 | return cr0; 74 | } 75 | 76 | ALWAYS_INLINE 77 | static inline void set_cr0 (mword cr0) 78 | { 79 | asm volatile ("mov %0, %%cr0" : : "r" (cr0)); 80 | } 81 | 82 | ALWAYS_INLINE 83 | static inline mword get_cr2() 84 | { 85 | mword cr2; 86 | asm volatile ("mov %%cr2, %0" : "=r" (cr2)); 87 | return cr2; 88 | } 89 | 90 | ALWAYS_INLINE 91 | static inline void set_cr2 (mword cr2) 92 | { 93 | asm volatile ("mov %0, %%cr2" : : "r" (cr2)); 94 | } 95 | 96 | ALWAYS_INLINE 97 | static inline mword get_cr4() 98 | { 99 | mword cr4; 100 | asm volatile ("mov %%cr4, %0" : "=r" (cr4)); 101 | return cr4; 102 | } 103 | 104 | ALWAYS_INLINE 105 | static inline void set_cr4 (mword cr4) 106 | { 107 | asm volatile ("mov %0, %%cr4" : : "r" (cr4)); 108 | } 109 | -------------------------------------------------------------------------------- /src/acpi_dmar.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "acpi_dmar.hpp" 22 | #include "cmdline.hpp" 23 | #include "dmar.hpp" 24 | #include "dpt.hpp" 25 | #include "hpet.hpp" 26 | #include "ioapic.hpp" 27 | #include "pci.hpp" 28 | #include "pd.hpp" 29 | 30 | void Acpi_dmar::parse() const 31 | { 32 | Dmar *dmar = new Dmar (static_cast(phys)); 33 | 34 | if (flags & 1) 35 | Pci::claim_all (dmar); 36 | 37 | for (Acpi_scope const *s = scope; s < reinterpret_cast(reinterpret_cast(this) + length); s = reinterpret_cast(reinterpret_cast(s) + s->length)) { 38 | 39 | switch (s->type) { 40 | case 1 ... 2: 41 | Pci::claim_dev (dmar, s->rid()); 42 | break; 43 | case 3: 44 | Ioapic::claim_dev (s->rid(), s->id); 45 | break; 46 | case 4: 47 | Hpet::claim_dev (s->rid(), s->id); 48 | break; 49 | } 50 | } 51 | } 52 | 53 | void Acpi_rmrr::parse() const 54 | { 55 | for (uint64 hpa = base & ~PAGE_MASK; hpa < limit; hpa += PAGE_SIZE) 56 | Pd::kern.dpt.update (hpa, 0, hpa, Dpt::DPT_R | Dpt::DPT_W); 57 | 58 | for (Acpi_scope const *s = scope; s < reinterpret_cast(reinterpret_cast(this) + length); s = reinterpret_cast(reinterpret_cast(s) + s->length)) { 59 | 60 | Dmar *dmar = nullptr; 61 | 62 | switch (s->type) { 63 | case 1: 64 | dmar = Pci::find_dmar (s->rid()); 65 | break; 66 | } 67 | 68 | if (dmar) 69 | dmar->assign (s->rid(), &Pd::kern); 70 | } 71 | } 72 | 73 | void Acpi_table_dmar::parse() const 74 | { 75 | if (!Cmdline::iommu) 76 | return; 77 | 78 | for (Acpi_remap const *r = remap; r < reinterpret_cast(reinterpret_cast(this) + length); r = reinterpret_cast(reinterpret_cast(r) + r->length)) { 79 | switch (r->type) { 80 | case Acpi_remap::DMAR: 81 | static_cast(r)->parse(); 82 | break; 83 | case Acpi_remap::RMRR: 84 | static_cast(r)->parse(); 85 | break; 86 | } 87 | } 88 | 89 | Dmar::enable (flags); 90 | } 91 | -------------------------------------------------------------------------------- /src/acpi_fadt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #include "acpi.hpp" 20 | #include "acpi_fadt.hpp" 21 | #include "io.hpp" 22 | #include "x86.hpp" 23 | 24 | void Acpi_table_fadt::parse() const 25 | { 26 | Acpi::irq = sci_irq; 27 | Acpi::feature = flags; 28 | 29 | // XXX: Use x_pm blocks if they exist 30 | 31 | if (pm1a_evt_blk) { 32 | Acpi::pm1a_sts.init (Acpi_gas::IO, pm1_evt_len >> 1, pm1a_evt_blk); 33 | Acpi::pm1a_ena.init (Acpi_gas::IO, pm1_evt_len >> 1, pm1a_evt_blk + (pm1_evt_len >> 1)); 34 | } 35 | if (pm1b_evt_blk) { 36 | Acpi::pm1b_sts.init (Acpi_gas::IO, pm1_evt_len >> 1, pm1b_evt_blk); 37 | Acpi::pm1b_ena.init (Acpi_gas::IO, pm1_evt_len >> 1, pm1b_evt_blk + (pm1_evt_len >> 1)); 38 | } 39 | 40 | if (pm1a_cnt_blk) 41 | Acpi::pm1a_cnt.init (Acpi_gas::IO, pm1_cnt_len, pm1a_cnt_blk); 42 | 43 | if (pm1b_cnt_blk) 44 | Acpi::pm1b_cnt.init (Acpi_gas::IO, pm1_cnt_len, pm1b_cnt_blk); 45 | 46 | if (pm2_cnt_blk) 47 | Acpi::pm2_cnt.init (Acpi_gas::IO, pm2_cnt_len, pm2_cnt_blk); 48 | 49 | if (pm_tmr_blk) 50 | Acpi::pm_tmr.init (Acpi_gas::IO, pm_tmr_len, pm_tmr_blk); 51 | 52 | if (length >= 129) { 53 | Acpi::reset_reg = reset_reg; 54 | Acpi::reset_val = reset_value; 55 | } 56 | 57 | if (smi_cmd && acpi_enable) { 58 | Io::out (smi_cmd, acpi_enable); 59 | while (!(Acpi::read (Acpi::PM1_CNT) & Acpi::PM1_CNT_SCI_EN)) 60 | pause(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/acpi_hpet.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 5 | * 6 | * This file is part of the NOVA microhypervisor. 7 | * 8 | * NOVA is free software: you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License version 2 as 10 | * published by the Free Software Foundation. 11 | * 12 | * NOVA is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License version 2 for more details. 16 | */ 17 | 18 | #include "acpi_hpet.hpp" 19 | #include "hpet.hpp" 20 | 21 | void Acpi_table_hpet::parse() const 22 | { 23 | if (hpet.asid == Acpi_gas::MEMORY) 24 | new Hpet (static_cast(hpet.addr), id); 25 | } 26 | -------------------------------------------------------------------------------- /src/acpi_madt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "acpi.hpp" 22 | #include "acpi_madt.hpp" 23 | #include "cpu.hpp" 24 | #include "gsi.hpp" 25 | #include "io.hpp" 26 | #include "ioapic.hpp" 27 | #include "lapic.hpp" 28 | #include "vectors.hpp" 29 | 30 | void Acpi_table_madt::parse() const 31 | { 32 | parse_entry (Acpi_apic::LAPIC, &parse_lapic); 33 | parse_entry (Acpi_apic::IOAPIC, &parse_ioapic); 34 | parse_entry (Acpi_apic::INTR, &parse_intr); 35 | 36 | if (flags & 1) { 37 | Io::out(0x20, 0x11); 38 | Io::out(0x21, VEC_GSI); 39 | Io::out(0x21, 0x4); 40 | Io::out(0x21, 0x1); 41 | Io::out(0x21, 0xff); 42 | } 43 | } 44 | 45 | void Acpi_table_madt::parse_entry (Acpi_apic::Type type, void (*handler)(Acpi_apic const *)) const 46 | { 47 | for (Acpi_apic const *ptr = apic; ptr < reinterpret_cast(reinterpret_cast(this) + length); ptr = reinterpret_cast(reinterpret_cast(ptr) + ptr->length)) 48 | if (ptr->type == type) 49 | (*handler)(ptr); 50 | } 51 | 52 | void Acpi_table_madt::parse_lapic (Acpi_apic const *ptr) 53 | { 54 | Acpi_lapic const *p = static_cast(ptr); 55 | 56 | if (p->flags & 1 && Cpu::online < NUM_CPU) 57 | Lapic::apic_id[Cpu::online++] = p->id; 58 | } 59 | 60 | void Acpi_table_madt::parse_ioapic (Acpi_apic const *ptr) 61 | { 62 | Acpi_ioapic const *p = static_cast(ptr); 63 | 64 | Ioapic *ioapic = new Ioapic (p->phys, p->id, p->gsi); 65 | 66 | unsigned gsi = p->gsi; 67 | unsigned max = ioapic->irt_max(); 68 | 69 | for (unsigned short i = 0; i <= max && gsi < NUM_GSI; i++, gsi++) 70 | Gsi::gsi_table[gsi].ioapic = ioapic; 71 | } 72 | 73 | void Acpi_table_madt::parse_intr (Acpi_apic const *ptr) 74 | { 75 | Acpi_intr const *p = static_cast(ptr); 76 | 77 | unsigned irq = p->irq; 78 | unsigned gsi = p->gsi; 79 | 80 | if (EXPECT_FALSE (gsi >= NUM_GSI || irq >= NUM_IRQ || p->bus)) 81 | return; 82 | 83 | Gsi::irq_table[irq] = gsi; 84 | 85 | Gsi::gsi_table[gsi].pol = p->flags.pol == Acpi_inti::POL_LOW || (p->flags.pol == Acpi_inti::POL_CONFORMING && irq == Acpi::irq); 86 | Gsi::gsi_table[gsi].trg = p->flags.trg == Acpi_inti::TRG_LEVEL || (p->flags.trg == Acpi_inti::TRG_CONFORMING && irq == Acpi::irq); 87 | 88 | if (irq == Acpi::irq) 89 | sci_overridden = true; 90 | } 91 | -------------------------------------------------------------------------------- /src/acpi_mcfg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "acpi_mcfg.hpp" 22 | #include "pci.hpp" 23 | 24 | void Acpi_table_mcfg::parse() const 25 | { 26 | for (Acpi_mcfg const *x = mcfg; x + 1 <= reinterpret_cast(reinterpret_cast(this) + length); x++) 27 | if (!x->seg) { 28 | Pci::bus_base = x->bus_s; 29 | Pci::cfg_base = static_cast(x->addr); 30 | Pci::cfg_size = ((x->bus_e - x->bus_s + 1) << 8) * PAGE_SIZE; 31 | } 32 | 33 | Pci::init(); 34 | } 35 | -------------------------------------------------------------------------------- /src/acpi_rsdp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #include "acpi.hpp" 20 | #include "acpi_rsdp.hpp" 21 | #include "hpt.hpp" 22 | 23 | Acpi_rsdp *Acpi_rsdp::find (mword start, unsigned len) 24 | { 25 | for (mword addr = start; addr < start + len; addr += 16) { 26 | Acpi_rsdp *rsdp = reinterpret_cast(addr); 27 | if (rsdp->good_signature() && rsdp->good_checksum()) 28 | return rsdp; 29 | } 30 | 31 | return nullptr; 32 | } 33 | 34 | void Acpi_rsdp::parse() 35 | { 36 | Acpi_rsdp *rsdp; 37 | 38 | mword map = reinterpret_cast(Hpt::remap (0)); 39 | 40 | if (!(rsdp = Acpi_rsdp::find (map + (*reinterpret_cast(map + 0x40e) << 4), 0x400)) && 41 | !(rsdp = Acpi_rsdp::find (map + 0xe0000, 0x20000))) 42 | return; 43 | 44 | Acpi::rsdt = rsdp->rsdt_addr; 45 | 46 | if (rsdp->revision > 1 && rsdp->good_checksum (rsdp->length)) 47 | Acpi::xsdt = static_cast(rsdp->xsdt_addr); 48 | } 49 | -------------------------------------------------------------------------------- /src/acpi_rsdt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "acpi.hpp" 22 | #include "acpi_rsdt.hpp" 23 | #include "hpt.hpp" 24 | 25 | struct Acpi_table_rsdt::table_map Acpi_table_rsdt::map[] INITDATA = 26 | { 27 | { SIG ('A','P','I','C'), &Acpi::madt }, 28 | { SIG ('D','M','A','R'), &Acpi::dmar }, 29 | { SIG ('F','A','C','P'), &Acpi::fadt }, 30 | { SIG ('H','P','E','T'), &Acpi::hpet }, 31 | { SIG ('M','C','F','G'), &Acpi::mcfg }, 32 | }; 33 | 34 | void Acpi_table_rsdt::parse (Paddr addr, size_t size) const 35 | { 36 | if (!good_checksum (addr)) 37 | return; 38 | 39 | unsigned long count = entries (size); 40 | 41 | Paddr table[count]; 42 | for (unsigned i = 0; i < count; i++) 43 | table[i] = static_cast(size == sizeof (*xsdt) ? xsdt[i] : rsdt[i]); 44 | 45 | for (unsigned i = 0; i < count; i++) { 46 | 47 | Acpi_table *acpi = static_cast(Hpt::remap (table[i])); 48 | 49 | if (acpi->good_checksum (table[i])) 50 | for (unsigned j = 0; j < sizeof map / sizeof *map; j++) 51 | if (acpi->signature == map[j].sig) 52 | *map[j].ptr = table[i]; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/acpi_table.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Configuration and Power Interface (ACPI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #include "acpi_table.hpp" 20 | #include "stdio.hpp" 21 | 22 | bool Acpi_table::good_checksum (Paddr addr) const 23 | { 24 | uint8 check = 0; 25 | 26 | for (uint8 const *ptr = reinterpret_cast(this); 27 | ptr < reinterpret_cast(this) + length; 28 | check = static_cast(check + *ptr++)) ; 29 | 30 | trace (TRACE_ACPI, "%.4s:%#010llx REV:%2u TBL:%8.8s OEM:%6.6s LEN:%5u (%s %#04x)", 31 | reinterpret_cast(&signature), 32 | static_cast(addr), 33 | revision, 34 | oem_table_id, 35 | oem_id, 36 | length, 37 | check ? "bad" : "ok", 38 | checksum); 39 | 40 | return !check; 41 | } 42 | -------------------------------------------------------------------------------- /src/bootstrap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Bootstrap Code 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "compiler.hpp" 22 | #include "ec.hpp" 23 | #include "hip.hpp" 24 | #include "msr.hpp" 25 | 26 | extern "C" NORETURN 27 | void bootstrap() 28 | { 29 | static mword barrier; 30 | 31 | Cpu::init(); 32 | 33 | // Create idle EC 34 | Ec::current = new Ec (Pd::current = &Pd::kern, Ec::idle, Cpu::id); 35 | Space_obj::insert_root (Sc::current = new Sc (&Pd::kern, Cpu::id, Ec::current)); 36 | 37 | // Barrier: wait for all ECs to arrive here 38 | for (Atomic::add (barrier, 1UL); barrier != Cpu::online; pause()) ; 39 | 40 | Msr::write(Msr::IA32_TSC, 0); 41 | 42 | // Create root task 43 | if (Cpu::bsp) { 44 | Hip::add_check(); 45 | Ec *root_ec = new Ec (&Pd::root, NUM_EXC + 1, &Pd::root, Ec::root_invoke, Cpu::id, 0, USER_ADDR - 2 * PAGE_SIZE, 0); 46 | Sc *root_sc = new Sc (&Pd::root, NUM_EXC + 2, root_ec, Cpu::id, Sc::default_prio, Sc::default_quantum); 47 | root_sc->remote_enqueue(); 48 | } 49 | 50 | Sc::schedule(); 51 | } 52 | -------------------------------------------------------------------------------- /src/cmdline.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Command Line Parser 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #include "cmdline.hpp" 20 | #include "hpt.hpp" 21 | #include "string.hpp" 22 | 23 | bool Cmdline::iommu; 24 | bool Cmdline::keyb; 25 | bool Cmdline::serial; 26 | bool Cmdline::spinner; 27 | bool Cmdline::vtlb; 28 | bool Cmdline::novga; 29 | bool Cmdline::novpid; 30 | 31 | struct Cmdline::param_map Cmdline::map[] INITDATA = 32 | { 33 | { "iommu", &Cmdline::iommu }, 34 | { "keyb", &Cmdline::keyb }, 35 | { "serial", &Cmdline::serial }, 36 | { "spinner", &Cmdline::spinner }, 37 | { "vtlb", &Cmdline::vtlb }, 38 | { "novga", &Cmdline::novga }, 39 | { "novpid", &Cmdline::novpid }, 40 | }; 41 | 42 | char *Cmdline::get_arg (char **line) 43 | { 44 | for (; **line == ' '; ++*line) ; 45 | 46 | if (!**line) 47 | return nullptr; 48 | 49 | char *arg = *line; 50 | 51 | for (; **line != ' '; ++*line) 52 | if (!**line) 53 | return arg; 54 | 55 | *(*line)++ = 0; 56 | 57 | return arg; 58 | } 59 | 60 | void Cmdline::init (mword addr) 61 | { 62 | char *arg, *line = static_cast(Hpt::remap (addr)); 63 | 64 | while ((arg = get_arg (&line))) 65 | for (unsigned i = 0; i < sizeof map / sizeof *map; i++) 66 | if (!strcmp (map[i].arg, arg)) 67 | *map[i].ptr = true; 68 | } 69 | -------------------------------------------------------------------------------- /src/console_serial.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Serial Console 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "cmdline.hpp" 22 | #include "console_serial.hpp" 23 | #include "hpt.hpp" 24 | #include "x86.hpp" 25 | 26 | INIT_PRIORITY (PRIO_CONSOLE) Console_serial Console_serial::con; 27 | 28 | Console_serial::Console_serial() 29 | { 30 | if (!Cmdline::serial) 31 | return; 32 | 33 | char *mem = static_cast(Hpt::remap (0)); 34 | if (!(base = *reinterpret_cast(mem + 0x400)) && 35 | !(base = *reinterpret_cast(mem + 0x402))) 36 | return; 37 | 38 | out (LCR, 0x80); 39 | out (DLL, (freq / 115200) & 0xff); 40 | out (DLM, (freq / 115200) >> 8); 41 | out (LCR, 3); 42 | out (IER, 0); 43 | out (FCR, 7); 44 | out (MCR, 3); 45 | 46 | enable(); 47 | } 48 | 49 | void Console_serial::putc (int c) 50 | { 51 | if (c == '\n') 52 | putc ('\r'); 53 | 54 | while (EXPECT_FALSE (!(in (LSR) & 0x20))) 55 | pause(); 56 | 57 | out (THR, c); 58 | } 59 | -------------------------------------------------------------------------------- /src/console_vga.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * VGA Console 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "cmdline.hpp" 22 | #include "console_vga.hpp" 23 | #include "pd.hpp" 24 | 25 | INIT_PRIORITY (PRIO_CONSOLE) Console_vga Console_vga::con; 26 | 27 | Console_vga::Console_vga() : num (25), row (0), col (0) 28 | { 29 | if (Cmdline::novga) 30 | return; 31 | 32 | Pd::kern.Space_mem::insert (HV_GLOBAL_FBUF, 0, Hpt::HPT_NX | Hpt::HPT_G | Hpt::HPT_UC | Hpt::HPT_W | Hpt::HPT_P, 0xb9000); 33 | 34 | set_page (1); 35 | 36 | enable(); 37 | } 38 | 39 | void Console_vga::setup() 40 | { 41 | if (Cmdline::novga || !Cmdline::spinner) 42 | return; 43 | 44 | for (unsigned c = 0; c < min (Cpu::online, 12U); c++) { 45 | 46 | if (row == --num) 47 | clear_row (row--); 48 | 49 | for (unsigned i = SPN_GSI; i < 80; i++) 50 | put (num, i, COLOR_LIGHT_BLACK, ((i - SPN_GSI) & 0xf)["0123456789ABCDEF"]); 51 | } 52 | } 53 | 54 | void Console_vga::putc (int c) 55 | { 56 | if (EXPECT_FALSE (c == '\f')) { 57 | clear_all(); 58 | row = col = 0; 59 | return; 60 | } 61 | 62 | if (EXPECT_TRUE (c != '\n')) { 63 | put (row, col, COLOR_LIGHT_WHITE, c); 64 | if (EXPECT_TRUE (++col < 80)) 65 | return; 66 | } 67 | 68 | col = 0; 69 | 70 | if (EXPECT_TRUE (++row == num)) 71 | clear_row (--row); 72 | } 73 | -------------------------------------------------------------------------------- /src/counter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Event Counters 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "counter.hpp" 22 | #include "stdio.hpp" 23 | #include "x86.hpp" 24 | 25 | unsigned Counter::ipi[NUM_IPI]; 26 | unsigned Counter::lvt[NUM_LVT]; 27 | unsigned Counter::gsi[NUM_GSI]; 28 | unsigned Counter::exc[NUM_EXC]; 29 | unsigned Counter::vmi[NUM_VMI]; 30 | unsigned Counter::vtlb_gpf; 31 | unsigned Counter::vtlb_hpf; 32 | unsigned Counter::vtlb_fill; 33 | unsigned Counter::vtlb_flush; 34 | unsigned Counter::schedule; 35 | unsigned Counter::helping; 36 | uint64 Counter::cycles_idle; 37 | 38 | void Counter::dump() 39 | { 40 | trace (0, "TIME: %16llu", rdtsc()); 41 | trace (0, "IDLE: %16llu", Counter::cycles_idle); 42 | trace (0, "VGPF: %16u", Counter::vtlb_gpf); 43 | trace (0, "VHPF: %16u", Counter::vtlb_hpf); 44 | trace (0, "VFIL: %16u", Counter::vtlb_fill); 45 | trace (0, "VFLU: %16u", Counter::vtlb_flush); 46 | trace (0, "SCHD: %16u", Counter::schedule); 47 | trace (0, "HELP: %16u", Counter::helping); 48 | 49 | Counter::vtlb_gpf = Counter::vtlb_hpf = Counter::vtlb_fill = Counter::vtlb_flush = Counter::schedule = Counter::helping = 0; 50 | 51 | for (unsigned i = 0; i < sizeof (Counter::ipi) / sizeof (*Counter::ipi); i++) 52 | if (Counter::ipi[i]) { 53 | trace (0, "IPI %#4x: %12u", i, Counter::ipi[i]); 54 | Counter::ipi[i] = 0; 55 | } 56 | 57 | for (unsigned i = 0; i < sizeof (Counter::lvt) / sizeof (*Counter::lvt); i++) 58 | if (Counter::lvt[i]) { 59 | trace (0, "LVT %#4x: %12u", i, Counter::lvt[i]); 60 | Counter::lvt[i] = 0; 61 | } 62 | 63 | for (unsigned i = 0; i < sizeof (Counter::gsi) / sizeof (*Counter::gsi); i++) 64 | if (Counter::gsi[i]) { 65 | trace (0, "GSI %#4x: %12u", i, Counter::gsi[i]); 66 | Counter::gsi[i] = 0; 67 | } 68 | 69 | for (unsigned i = 0; i < sizeof (Counter::exc) / sizeof (*Counter::exc); i++) 70 | if (Counter::exc[i]) { 71 | trace (0, "EXC %#4x: %12u", i, Counter::exc[i]); 72 | Counter::exc[i] = 0; 73 | } 74 | 75 | for (unsigned i = 0; i < sizeof (Counter::vmi) / sizeof (*Counter::vmi); i++) 76 | if (Counter::vmi[i]) { 77 | trace (0, "VMI %#4x: %12u", i, Counter::vmi[i]); 78 | Counter::vmi[i] = 0; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/fpu.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Floating Point Unit (FPU) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #include "fpu.hpp" 20 | 21 | INIT_PRIORITY (PRIO_SLAB) 22 | Slab_cache Fpu::cache (sizeof (Fpu), 16); 23 | -------------------------------------------------------------------------------- /src/gdt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Global Descriptor Table (GDT) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "gdt.hpp" 22 | #include "memory.hpp" 23 | #include "tss.hpp" 24 | 25 | ALIGNED(8) Gdt Gdt::gdt[SEL_MAX >> 3]; 26 | 27 | void Gdt::build() 28 | { 29 | #ifdef __i386__ 30 | Size s = BIT_32; 31 | bool l = false; 32 | #else 33 | Size s = BIT_16; 34 | bool l = true; 35 | #endif 36 | gdt[SEL_KERN_CODE >> 3].set32 (CODE_XRA, PAGES, s, l, 0, 0, ~0ul); 37 | gdt[SEL_KERN_DATA >> 3].set32 (DATA_RWA, PAGES, s, l, 0, 0, ~0ul); 38 | 39 | gdt[SEL_USER_CODE >> 3].set32 (CODE_XRA, PAGES, s, l, 3, 0, ~0ul); 40 | gdt[SEL_USER_DATA >> 3].set32 (DATA_RWA, PAGES, s, l, 3, 0, ~0ul); 41 | gdt[SEL_USER_CODE_L >> 3].set32 (CODE_XRA, PAGES, s, l, 3, 0, ~0ul); 42 | 43 | #ifdef __i386__ 44 | gdt[SEL_TSS_RUN >> 3].set32 (SYS_TSS, BYTES, BIT_16, false, 0, reinterpret_cast(&Tss::run), SPC_LOCAL_IOP_E - reinterpret_cast(&Tss::run)); 45 | gdt[SEL_TSS_DBF >> 3].set32 (SYS_TSS, BYTES, BIT_16, false, 0, reinterpret_cast(&Tss::dbf), sizeof (Tss) - 1); 46 | #else 47 | gdt[SEL_TSS_RUN >> 3].set64 (SYS_TSS, BYTES, BIT_16, false, 0, reinterpret_cast(&Tss::run), SPC_LOCAL_IOP_E - reinterpret_cast(&Tss::run)); 48 | gdt[SEL_TSS_DBF >> 3].set64 (SYS_TSS, BYTES, BIT_16, false, 0, reinterpret_cast(&Tss::dbf), sizeof (Tss) - 1); 49 | #endif 50 | } 51 | -------------------------------------------------------------------------------- /src/gsi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Global System Interrupts (GSI) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "acpi.hpp" 22 | #include "dmar.hpp" 23 | #include "gsi.hpp" 24 | #include "ioapic.hpp" 25 | #include "keyb.hpp" 26 | #include "lapic.hpp" 27 | #include "sm.hpp" 28 | #include "vectors.hpp" 29 | 30 | Gsi Gsi::gsi_table[NUM_GSI]; 31 | unsigned Gsi::irq_table[NUM_IRQ]; 32 | 33 | void Gsi::setup() 34 | { 35 | for (unsigned gsi = 0; gsi < NUM_GSI; gsi++) { 36 | 37 | Space_obj::insert_root (Gsi::gsi_table[gsi].sm = new Sm (&Pd::kern, NUM_CPU + gsi)); 38 | 39 | gsi_table[gsi].vec = static_cast(VEC_GSI + gsi); 40 | 41 | if (gsi < NUM_IRQ) { 42 | irq_table[gsi] = gsi; 43 | gsi_table[gsi].trg = 0; 44 | gsi_table[gsi].pol = 0; 45 | } else { 46 | gsi_table[gsi].trg = 1; 47 | gsi_table[gsi].pol = 1; 48 | } 49 | } 50 | } 51 | 52 | uint64 Gsi::set (unsigned gsi, unsigned cpu, unsigned rid) 53 | { 54 | uint32 msi_addr = 0, msi_data = 0, aid = Lapic::apic_id[cpu]; 55 | 56 | Ioapic *ioapic = gsi_table[gsi].ioapic; 57 | 58 | if (ioapic) { 59 | ioapic->set_cpu (gsi, Dmar::ire() ? 0 : aid); 60 | ioapic->set_irt (gsi, gsi_table[gsi].irt); 61 | rid = ioapic->get_rid(); 62 | } else { 63 | msi_addr = 0xfee00000 | (Dmar::ire() ? 3U << 3 : aid << 12); 64 | msi_data = Dmar::ire() ? gsi : gsi_table[gsi].vec; 65 | } 66 | 67 | Dmar::set_irt (gsi, rid, aid, VEC_GSI + gsi, gsi_table[gsi].trg); 68 | 69 | return static_cast(msi_addr) << 32 | msi_data; 70 | } 71 | 72 | void Gsi::mask (unsigned gsi) 73 | { 74 | Ioapic *ioapic = gsi_table[gsi].ioapic; 75 | 76 | if (ioapic) 77 | ioapic->set_irt (gsi, 1U << 16 | gsi_table[gsi].irt); 78 | } 79 | 80 | void Gsi::unmask (unsigned gsi) 81 | { 82 | Ioapic *ioapic = gsi_table[gsi].ioapic; 83 | 84 | if (ioapic) 85 | ioapic->set_irt (gsi, 0U << 16 | gsi_table[gsi].irt); 86 | } 87 | 88 | void Gsi::vector (unsigned vector) 89 | { 90 | unsigned gsi = vector - VEC_GSI; 91 | 92 | if (gsi == Keyb::gsi) 93 | Keyb::interrupt(); 94 | 95 | else if (gsi == Acpi::gsi) 96 | Acpi::interrupt(); 97 | 98 | else if (gsi_table[gsi].trg) 99 | mask (gsi); 100 | 101 | Lapic::eoi(); 102 | 103 | gsi_table[gsi].sm->up(); 104 | 105 | Counter::print<1,16> (++Counter::gsi[gsi], Console_vga::Color (Console_vga::COLOR_LIGHT_YELLOW - gsi / 64), SPN_GSI + gsi % 64); 106 | } 107 | -------------------------------------------------------------------------------- /src/hpet.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * High Precision Event Timer (HPET) 3 | * 4 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 5 | * 6 | * This file is part of the NOVA microhypervisor. 7 | * 8 | * NOVA is free software: you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License version 2 as 10 | * published by the Free Software Foundation. 11 | * 12 | * NOVA is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License version 2 for more details. 16 | */ 17 | 18 | #include "hpet.hpp" 19 | 20 | INIT_PRIORITY (PRIO_SLAB) 21 | Slab_cache Hpet::cache (sizeof (Hpet), 8); 22 | 23 | Hpet *Hpet::list; 24 | -------------------------------------------------------------------------------- /src/hpt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Host Page Table (HPT) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "assert.hpp" 22 | #include "bits.hpp" 23 | #include "hpt.hpp" 24 | 25 | bool Hpt::sync_from (Hpt src, mword v, mword o) 26 | { 27 | mword l = (bit_scan_reverse (v ^ o) - PAGE_BITS) / bpl(); 28 | 29 | Hpt *s = static_cast(src.walk (v, l, false)); 30 | if (!s) 31 | return false; 32 | 33 | Hpt *d = static_cast(walk (v, l)); 34 | assert (d); 35 | 36 | if (d->val == s->val) 37 | return false; 38 | 39 | d->val = s->val; 40 | 41 | return true; 42 | } 43 | 44 | void Hpt::sync_master_range (mword s, mword e) 45 | { 46 | for (mword l = (bit_scan_reverse (LINK_ADDR ^ CPU_LOCAL) - PAGE_BITS) / bpl(); s < e; s += 1UL << (l * bpl() + PAGE_BITS)) 47 | sync_from (Hptp (reinterpret_cast(&PDBR)), s, CPU_LOCAL); 48 | } 49 | 50 | Paddr Hpt::replace (mword v, mword p) 51 | { 52 | Hpt o, *e = walk (v, 0); assert (e); 53 | 54 | do o = *e; while (o.val != p && !(o.attr() & HPT_W) && !e->set (o.val, p)); 55 | 56 | return e->addr(); 57 | } 58 | 59 | void *Hpt::remap (Paddr phys) 60 | { 61 | Hptp hpt (current()); 62 | 63 | size_t size = 1UL << (bpl() + PAGE_BITS); 64 | 65 | mword offset = phys & (size - 1); 66 | 67 | phys &= ~offset; 68 | 69 | Paddr old; mword attr; 70 | if (hpt.lookup (SPC_LOCAL_REMAP, old, attr)) { 71 | hpt.update (SPC_LOCAL_REMAP, bpl(), 0, 0, Hpt::TYPE_DN); flush (SPC_LOCAL_REMAP); 72 | hpt.update (SPC_LOCAL_REMAP + size, bpl(), 0, 0, Hpt::TYPE_DN); flush (SPC_LOCAL_REMAP + size); 73 | } 74 | 75 | hpt.update (SPC_LOCAL_REMAP, bpl(), phys, HPT_W | HPT_P); 76 | hpt.update (SPC_LOCAL_REMAP + size, bpl(), phys + size, HPT_W | HPT_P); 77 | 78 | return reinterpret_cast(SPC_LOCAL_REMAP + offset); 79 | } 80 | -------------------------------------------------------------------------------- /src/idt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Interrupt Descriptor Table (IDT) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #include "extern.hpp" 20 | #include "idt.hpp" 21 | #include "selectors.hpp" 22 | 23 | ALIGNED(8) Idt Idt::idt[VEC_MAX]; 24 | 25 | void Idt::build() 26 | { 27 | mword *ptr = handlers; 28 | 29 | for (unsigned vector = 0; vector < VEC_MAX; vector++, ptr++) 30 | if (*ptr) 31 | idt[vector].set (SYS_INTR_GATE, *ptr & 3, SEL_KERN_CODE, *ptr & ~3); 32 | else 33 | idt[vector].set (SYS_TASK_GATE, 0, SEL_TSS_DBF, 0); 34 | } 35 | -------------------------------------------------------------------------------- /src/init.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Initialization Code 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "acpi.hpp" 22 | #include "compiler.hpp" 23 | #include "console_serial.hpp" 24 | #include "console_vga.hpp" 25 | #include "gsi.hpp" 26 | #include "hip.hpp" 27 | #include "hpt.hpp" 28 | #include "idt.hpp" 29 | #include "keyb.hpp" 30 | 31 | extern "C" INIT 32 | mword kern_ptab_setup() 33 | { 34 | Hptp hpt; 35 | 36 | // Allocate and map cpu page 37 | hpt.update (CPU_LOCAL_DATA, 0, 38 | Buddy::ptr_to_phys (Buddy::allocator.alloc (0, Buddy::FILL_0)), 39 | Hpt::HPT_NX | Hpt::HPT_G | Hpt::HPT_W | Hpt::HPT_P); 40 | 41 | // Allocate and map kernel stack 42 | hpt.update (CPU_LOCAL_STCK, 0, 43 | Buddy::ptr_to_phys (Buddy::allocator.alloc (0, Buddy::FILL_0)), 44 | Hpt::HPT_NX | Hpt::HPT_G | Hpt::HPT_W | Hpt::HPT_P); 45 | 46 | // Sync kernel code and data 47 | hpt.sync_master_range (LINK_ADDR, CPU_LOCAL); 48 | 49 | return hpt.addr(); 50 | } 51 | 52 | extern "C" INIT REGPARM (1) 53 | void init (mword mbi) 54 | { 55 | // Setup 0-page and 1-page 56 | memset (reinterpret_cast(&PAGE_0), 0, PAGE_SIZE); 57 | memset (reinterpret_cast(&PAGE_1), ~0u, PAGE_SIZE); 58 | 59 | for (void (**func)() = &CTORS_G; func != &CTORS_E; (*func++)()) ; 60 | 61 | Hip::build (mbi); 62 | 63 | for (void (**func)() = &CTORS_C; func != &CTORS_G; (*func++)()) ; 64 | 65 | // Now we're ready to talk to the world 66 | Console::print ("\fNOVA Microhypervisor v%u-%07lx (%s): %s %s [%s]\n", CFG_VER, reinterpret_cast(&GIT_VER), ARCH, __DATE__, __TIME__, COMPILER_STRING); 67 | 68 | Idt::build(); 69 | Gsi::setup(); 70 | Acpi::setup(); 71 | 72 | Console_vga::con.setup(); 73 | 74 | Keyb::init(); 75 | } 76 | -------------------------------------------------------------------------------- /src/ioapic.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * I/O Advanced Programmable Interrupt Controller (IOAPIC) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "ioapic.hpp" 22 | #include "pd.hpp" 23 | #include "stdio.hpp" 24 | 25 | INIT_PRIORITY (PRIO_SLAB) 26 | Slab_cache Ioapic::cache (sizeof (Ioapic), 8); 27 | 28 | Ioapic *Ioapic::list; 29 | 30 | Ioapic::Ioapic (Paddr p, unsigned i, unsigned g) : List (list), reg_base ((hwdev_addr -= PAGE_SIZE) | (p & PAGE_MASK)), gsi_base (g), id (i), rid (0) 31 | { 32 | Pd::kern.Space_mem::delreg (p & ~PAGE_MASK); 33 | Pd::kern.Space_mem::insert (reg_base, 0, Hpt::HPT_NX | Hpt::HPT_G | Hpt::HPT_UC | Hpt::HPT_W | Hpt::HPT_P, p & ~PAGE_MASK); 34 | 35 | trace (TRACE_APIC, "APIC:%#lx ID:%#x VER:%#x IRT:%#x PRQ:%u GSI:%u", 36 | p, i, version(), irt_max(), prq(), gsi_base); 37 | } 38 | -------------------------------------------------------------------------------- /src/keyb.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Keyboard 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "acpi.hpp" 22 | #include "counter.hpp" 23 | #include "cmdline.hpp" 24 | #include "gsi.hpp" 25 | #include "keyb.hpp" 26 | #include "stdio.hpp" 27 | 28 | unsigned Keyb::gsi = ~0u; 29 | 30 | void Keyb::init() 31 | { 32 | if (!Cmdline::keyb) 33 | return; 34 | 35 | while (status() & STS_OUTB) 36 | output(); 37 | 38 | gsi = Gsi::irq_to_gsi (irq); 39 | 40 | trace (TRACE_KEYB, "KEYB: GSI:%#x", gsi); 41 | 42 | Gsi::set (gsi); 43 | } 44 | 45 | void Keyb::interrupt() 46 | { 47 | unsigned sts; 48 | 49 | while ((sts = status()) & STS_OUTB) { 50 | 51 | unsigned out = output(); 52 | 53 | if (sts & STS_AUXB) 54 | continue; 55 | 56 | if (out & 0x80) 57 | continue; 58 | 59 | switch (out) { 60 | case 0x1: // esc 61 | Acpi::reset(); 62 | Io::out(0xcf9, 0x6); 63 | break; 64 | case 0x2e: // c 65 | Counter::dump(); 66 | break; 67 | case 0x3b ... 0x42: // f1-f8 68 | Console_vga::con.set_page (out - 0x3b); 69 | break; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/mca.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Machine-Check Architecture (MCA) 3 | * 4 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 5 | * 6 | * This file is part of the NOVA microhypervisor. 7 | * 8 | * NOVA is free software: you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License version 2 as 10 | * published by the Free Software Foundation. 11 | * 12 | * NOVA is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License version 2 for more details. 16 | */ 17 | 18 | #include "compiler.hpp" 19 | #include "cpu.hpp" 20 | #include "mca.hpp" 21 | #include "msr.hpp" 22 | #include "stdio.hpp" 23 | #include "x86.hpp" 24 | 25 | unsigned Mca::banks; 26 | 27 | void Mca::init() 28 | { 29 | if (EXPECT_FALSE (!Cpu::feature (Cpu::FEAT_MCE))) 30 | return; 31 | 32 | set_cr4 (get_cr4() | Cpu::CR4_MCE); 33 | 34 | if (EXPECT_FALSE (!Cpu::feature (Cpu::FEAT_MCA))) 35 | return; 36 | 37 | uint32 cap = Msr::read(Msr::IA32_MCG_CAP); 38 | 39 | Msr::write(Msr::IA32_MCG_STATUS, 0); 40 | 41 | if (cap & 0x100) 42 | Msr::write(Msr::IA32_MCG_CTL, ~0ULL); 43 | 44 | banks = cap & 0xff; 45 | 46 | for (unsigned i = (Cpu::vendor == Cpu::INTEL && Cpu::family == 6 && Cpu::model < 0x1a); i < banks; i++) { 47 | Msr::write(Msr::Register (4 * i + Msr::IA32_MCI_CTL), ~0ULL); 48 | Msr::write(Msr::Register (4 * i + Msr::IA32_MCI_STATUS), 0); 49 | } 50 | } 51 | 52 | void Mca::vector() 53 | { 54 | uint64 sts; 55 | 56 | for (unsigned i = 0; i < banks; i++) 57 | if ((sts = Msr::read(Msr::Register (4 * i + Msr::IA32_MCI_STATUS))) & 1ULL << 63) 58 | trace (TRACE_ERROR, "Machine Check B%u: %#018llx", i, sts); 59 | } 60 | -------------------------------------------------------------------------------- /src/mdb.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Mapping Database 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #include "assert.hpp" 20 | #include "lock_guard.hpp" 21 | #include "mdb.hpp" 22 | 23 | INIT_PRIORITY (PRIO_SLAB) 24 | Slab_cache Mdb::cache (sizeof (Mdb), 16); 25 | 26 | Spinlock Mdb::lock; 27 | 28 | bool Mdb::insert_node (Mdb *p, mword a) 29 | { 30 | Lock_guard guard (lock); 31 | 32 | if (!p->alive()) 33 | return false; 34 | 35 | if (!(node_attr = p->node_attr & a)) 36 | return false; 37 | 38 | prev = prnt = p; 39 | next = p->next; 40 | dpth = static_cast(p->dpth + 1); 41 | p->next = p->next->prev = this; 42 | 43 | return true; 44 | } 45 | 46 | void Mdb::demote_node (mword a) 47 | { 48 | Lock_guard guard (lock); 49 | 50 | node_attr &= ~a; 51 | } 52 | 53 | bool Mdb::remove_node() 54 | { 55 | if (node_attr) 56 | return false; 57 | 58 | Lock_guard guard (lock); 59 | 60 | if (!alive()) 61 | return false; 62 | 63 | if (next->dpth > dpth) 64 | return false; 65 | 66 | next->prev = prev; 67 | prev->next = next; 68 | 69 | return true; 70 | } 71 | -------------------------------------------------------------------------------- /src/memory.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Virtual-Memory Layout 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "memory.hpp" 22 | #include "types.hpp" 23 | 24 | mword hwdev_addr = HV_GLOBAL_FBUF; 25 | -------------------------------------------------------------------------------- /src/mtrr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Memory Type Range Registers (MTRR) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "msr.hpp" 22 | #include "mtrr.hpp" 23 | 24 | unsigned Mtrr::count; 25 | unsigned Mtrr::dtype; 26 | Mtrr * Mtrr::list; 27 | 28 | INIT_PRIORITY (PRIO_SLAB) 29 | Slab_cache Mtrr::cache (sizeof (Mtrr), 8); 30 | 31 | void Mtrr::init() 32 | { 33 | count = Msr::read(Msr::IA32_MTRR_CAP) & 0xff; 34 | dtype = Msr::read(Msr::IA32_MTRR_DEF_TYPE) & 0xff; 35 | 36 | for (unsigned i = 0; i < count; i++) 37 | new Mtrr (Msr::read(Msr::Register (Msr::IA32_MTRR_PHYS_BASE + 2 * i)), 38 | Msr::read(Msr::Register (Msr::IA32_MTRR_PHYS_MASK + 2 * i))); 39 | } 40 | 41 | unsigned Mtrr::memtype (uint64 phys, uint64 &next) 42 | { 43 | if (phys < 0x80000) { 44 | next = 1 + (phys | 0xffff); 45 | return static_cast(Msr::read(Msr::IA32_MTRR_FIX64K_BASE) >> 46 | (phys >> 13 & 0x38)) & 0xff; 47 | } 48 | 49 | if (phys < 0xc0000) { 50 | next = 1 + (phys | 0x3fff); 51 | return static_cast(Msr::read(Msr::Register (Msr::IA32_MTRR_FIX16K_BASE + (phys >> 17 & 0x1))) >> 52 | (phys >> 11 & 0x38)) & 0xff; 53 | } 54 | 55 | if (phys < 0x100000) { 56 | next = 1 + (phys | 0xfff); 57 | return static_cast(Msr::read(Msr::Register (Msr::IA32_MTRR_FIX4K_BASE + (phys >> 15 & 0x7))) >> 58 | (phys >> 9 & 0x38)) & 0xff; 59 | } 60 | 61 | unsigned type = ~0U; next = ~0ULL; 62 | 63 | for (Mtrr *mtrr = list; mtrr; mtrr = mtrr->next) { 64 | 65 | if (!(mtrr->mask & 0x800)) 66 | continue; 67 | 68 | uint64 base = mtrr->base & ~PAGE_MASK; 69 | 70 | if (phys < base) 71 | next = min (next, base); 72 | 73 | else if (((phys ^ mtrr->base) & mtrr->mask) >> PAGE_BITS == 0) { 74 | next = min (next, base + mtrr->size()); 75 | type = min (type, static_cast(mtrr->base) & 0xff); 76 | } 77 | } 78 | 79 | return type == ~0U ? dtype : type; 80 | } 81 | -------------------------------------------------------------------------------- /src/pci.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PCI Configuration Space 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "pci.hpp" 22 | #include "pd.hpp" 23 | #include "stdio.hpp" 24 | 25 | INIT_PRIORITY (PRIO_SLAB) 26 | Slab_cache Pci::cache (sizeof (Pci), 8); 27 | 28 | unsigned Pci::bus_base; 29 | Paddr Pci::cfg_base; 30 | size_t Pci::cfg_size; 31 | Pci * Pci::list; 32 | 33 | struct Pci::quirk_map Pci::map[] INITDATA = 34 | { 35 | }; 36 | 37 | Pci::Pci (unsigned r, unsigned l) : List (list), reg_base (hwdev_addr -= PAGE_SIZE), rid (static_cast(r)), lev (static_cast(l)) 38 | { 39 | Pd::kern.Space_mem::insert (reg_base, 0, Hpt::HPT_NX | Hpt::HPT_G | Hpt::HPT_UC | Hpt::HPT_W | Hpt::HPT_P, cfg_base + (rid << PAGE_BITS)); 40 | 41 | for (unsigned i = 0; i < sizeof map / sizeof *map; i++) 42 | if (read(REG_VID) == map[i].vid && read(REG_DID) == map[i].did) 43 | (this->*map[i].func)(); 44 | } 45 | 46 | void Pci::init (unsigned b, unsigned l) 47 | { 48 | for (unsigned r = b << 8; r < (b + 1) << 8; r++) { 49 | 50 | if (*static_cast(Hpt::remap (cfg_base + (r << PAGE_BITS))) == ~0U) 51 | continue; 52 | 53 | Pci *p = new Pci (r, l); 54 | 55 | unsigned h = p->read(REG_HDR); 56 | 57 | if ((h & 0x7f) == 1) 58 | init (p->read(REG_SBUSN), l + 1); 59 | 60 | if (!(r & 0x7) && !(h & 0x80)) 61 | r += 7; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/pt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Portal 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "ec.hpp" 22 | #include "pt.hpp" 23 | #include "stdio.hpp" 24 | 25 | INIT_PRIORITY (PRIO_SLAB) 26 | Slab_cache Pt::cache (sizeof (Pt), 32); 27 | 28 | Pt::Pt (Pd *own, mword sel, Ec *e, Mtd m, mword addr) : Kobject (PT, static_cast(own), sel, 0x3), ec (e), mtd (m), ip (addr), id (0) 29 | { 30 | trace (TRACE_SYSCALL, "PT:%p created (EC:%p IP:%#lx)", this, e, ip); 31 | } 32 | -------------------------------------------------------------------------------- /src/pte.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Page Table Entry (PTE) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "dpt.hpp" 22 | #include "ept.hpp" 23 | #include "hpt.hpp" 24 | #include "pte.hpp" 25 | 26 | mword Dpt::ord = ~0UL; 27 | mword Ept::ord = ~0UL; 28 | mword Hpt::ord = ~0UL; 29 | 30 | template 31 | P *Pte::walk (E v, unsigned long n, bool a) 32 | { 33 | unsigned long l = L; 34 | 35 | for (P *p, *e = static_cast

(this);; e = static_cast

(Buddy::phys_to_ptr (e->addr())) + (v >> (--l * B + PAGE_BITS) & ((1UL << B) - 1))) { 36 | 37 | if (l == n) 38 | return e; 39 | 40 | if (!e->val) { 41 | 42 | if (!a) 43 | return nullptr; 44 | 45 | if (!e->set (0, Buddy::ptr_to_phys (p = new P) | (l == L ? 0 : P::PTE_N))) 46 | delete p; 47 | } 48 | } 49 | } 50 | 51 | template 52 | size_t Pte::lookup (E v, Paddr &p, mword &a) 53 | { 54 | unsigned long l = L; 55 | 56 | for (P *e = static_cast

(this);; e = static_cast

(Buddy::phys_to_ptr (e->addr())) + (v >> (--l * B + PAGE_BITS) & ((1UL << B) - 1))) { 57 | 58 | if (EXPECT_FALSE (!e->val)) 59 | return 0; 60 | 61 | if (EXPECT_FALSE (l && !e->super())) 62 | continue; 63 | 64 | size_t s = 1UL << (l * B + e->order()); 65 | 66 | p = static_cast(e->addr() | (v & (s - 1))); 67 | 68 | a = e->attr(); 69 | 70 | return s; 71 | } 72 | } 73 | 74 | template 75 | void Pte::update (E v, mword o, E p, mword a, Type t) 76 | { 77 | unsigned long l = o / B, n = 1UL << o % B, s; 78 | 79 | P *e = walk (v, l, t == TYPE_UP); 80 | 81 | if (!e) 82 | return; 83 | 84 | if (a) { 85 | p |= P::order (o % B) | (l ? P::PTE_S : 0) | a; 86 | s = 1UL << (l * B + PAGE_BITS); 87 | } else 88 | p = s = 0; 89 | 90 | for (unsigned long i = 0; i < n; e[i].val = p, i++, p += s) { 91 | 92 | if (!e[i].val) 93 | continue; 94 | 95 | if (l && !e[i].super()) 96 | delete static_cast

(Buddy::phys_to_ptr (e[i].addr())); 97 | } 98 | 99 | if (F) 100 | flush (e, n * sizeof (E)); 101 | } 102 | 103 | template class Pte; 104 | template class Pte; 105 | template class Pte; 106 | -------------------------------------------------------------------------------- /src/rcu.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Read-Copy Update (RCU) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "atomic.hpp" 22 | #include "barrier.hpp" 23 | #include "counter.hpp" 24 | #include "cpu.hpp" 25 | #include "hazards.hpp" 26 | #include "initprio.hpp" 27 | #include "rcu.hpp" 28 | #include "stdio.hpp" 29 | 30 | mword Rcu::state = RCU_CMP; 31 | mword Rcu::count; 32 | 33 | mword Rcu::l_batch; 34 | mword Rcu::c_batch; 35 | 36 | INIT_PRIORITY (PRIO_LOCAL) Rcu_list Rcu::next; 37 | INIT_PRIORITY (PRIO_LOCAL) Rcu_list Rcu::curr; 38 | INIT_PRIORITY (PRIO_LOCAL) Rcu_list Rcu::done; 39 | 40 | void Rcu::invoke_batch() 41 | { 42 | for (Rcu_elem *e = done.head, *n; e; e = n) { 43 | n = e->next; 44 | (e->func)(e); 45 | } 46 | 47 | done.clear(); 48 | } 49 | 50 | void Rcu::start_batch (State s) 51 | { 52 | mword v, m = RCU_CMP | RCU_PND; 53 | 54 | do if ((v = state) >> 2 != l_batch) return; while (!(v & s) && !Atomic::cmp_swap (state, v, v | s)); 55 | 56 | if ((v ^ ~s) & m) 57 | return; 58 | 59 | count = Cpu::online; 60 | 61 | barrier(); 62 | 63 | state++; 64 | } 65 | 66 | void Rcu::quiet() 67 | { 68 | Cpu::hazard &= ~HZD_RCU; 69 | 70 | if (Atomic::sub (count, 1UL) == 0) 71 | start_batch (RCU_CMP); 72 | } 73 | 74 | void Rcu::update() 75 | { 76 | if (l_batch != batch()) { 77 | l_batch = batch(); 78 | Cpu::hazard |= HZD_RCU; 79 | Counter::print<1,16> (l_batch, Console_vga::COLOR_LIGHT_GREEN, SPN_RCU); 80 | } 81 | 82 | if (curr.head && complete (c_batch)) 83 | done.append (&curr); 84 | 85 | if (!curr.head && next.head) { 86 | curr.append (&next); 87 | 88 | c_batch = l_batch + 1; 89 | 90 | start_batch (RCU_PND); 91 | } 92 | 93 | if (done.head) 94 | invoke_batch(); 95 | } 96 | -------------------------------------------------------------------------------- /src/sm.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Semaphore 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "sm.hpp" 22 | #include "stdio.hpp" 23 | 24 | INIT_PRIORITY (PRIO_SLAB) 25 | Slab_cache Sm::cache (sizeof (Sm), 32); 26 | 27 | Sm::Sm (Pd *own, mword sel, mword cnt) : Kobject (SM, static_cast(own), sel, 0x3), counter (cnt) 28 | { 29 | trace (TRACE_SYSCALL, "SM:%p created (CNT:%lu)", this, cnt); 30 | } 31 | -------------------------------------------------------------------------------- /src/space_obj.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Object Space 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "pd.hpp" 22 | 23 | Space_mem *Space_obj::space_mem() 24 | { 25 | return static_cast(this); 26 | } 27 | 28 | Paddr Space_obj::walk (mword idx) 29 | { 30 | mword virt = idx_to_virt (idx); Paddr phys; void *ptr; 31 | 32 | if (!space_mem()->lookup (virt, phys) || (phys & ~PAGE_MASK) == reinterpret_cast(&FRAME_0)) { 33 | 34 | Paddr p = Buddy::ptr_to_phys (ptr = Buddy::allocator.alloc (0, Buddy::FILL_0)); 35 | 36 | if ((phys = space_mem()->replace (virt, p | Hpt::HPT_NX | Hpt::HPT_D | Hpt::HPT_A | Hpt::HPT_W | Hpt::HPT_P)) != p) 37 | Buddy::allocator.free (reinterpret_cast(ptr)); 38 | 39 | phys |= virt & PAGE_MASK; 40 | } 41 | 42 | return phys; 43 | } 44 | 45 | void Space_obj::update (mword idx, Capability cap) 46 | { 47 | *static_cast(Buddy::phys_to_ptr (walk (idx))) = cap; 48 | } 49 | 50 | size_t Space_obj::lookup (mword idx, Capability &cap) 51 | { 52 | Paddr phys; 53 | if (!space_mem()->lookup (idx_to_virt (idx), phys) || (phys & ~PAGE_MASK) == reinterpret_cast(&FRAME_0)) 54 | return 0; 55 | 56 | cap = *static_cast(Buddy::phys_to_ptr (phys)); 57 | 58 | return 1; 59 | } 60 | 61 | void Space_obj::update (Mdb *mdb, mword r) 62 | { 63 | assert (this == mdb->space && this != &Pd::kern); 64 | Lock_guard guard (mdb->node_lock); 65 | update (mdb->node_base, Capability (reinterpret_cast(mdb->node_phys), mdb->node_attr & ~r)); 66 | } 67 | 68 | bool Space_obj::insert_root (Kobject *obj) 69 | { 70 | if (!obj->space->tree_insert (obj)) 71 | return false; 72 | 73 | if (obj->space != static_cast(&Pd::kern)) 74 | static_cast(obj->space)->update (obj->node_base, Capability (obj, obj->node_attr)); 75 | 76 | return true; 77 | } 78 | 79 | void Space_obj::page_fault (mword addr, mword error) 80 | { 81 | assert (!(error & Hpt::ERR_W)); 82 | 83 | for (; !Pd::current->Space_mem::loc[Cpu::id].sync_from (Pd::current->Space_mem::hpt, addr, CPU_LOCAL);) 84 | Pd::current->Space_mem::replace (addr, reinterpret_cast(&FRAME_0) | Hpt::HPT_NX | Hpt::HPT_A | Hpt::HPT_P); 85 | } 86 | -------------------------------------------------------------------------------- /src/space_pio.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Port I/O Space 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "pd.hpp" 22 | 23 | Space_mem *Space_pio::space_mem() 24 | { 25 | return static_cast(this); 26 | } 27 | 28 | Paddr Space_pio::walk (bool host, mword idx) 29 | { 30 | Paddr &bmp = host ? hbmp : gbmp; 31 | 32 | if (!bmp) { 33 | bmp = Buddy::ptr_to_phys (Buddy::allocator.alloc (1, Buddy::FILL_1)); 34 | 35 | if (host) 36 | space_mem()->insert (SPC_LOCAL_IOP, 1, Hpt::HPT_NX | Hpt::HPT_D | Hpt::HPT_A | Hpt::HPT_W | Hpt::HPT_P, bmp); 37 | } 38 | 39 | return bmp | (idx_to_virt (idx) & (2 * PAGE_SIZE - 1)); 40 | } 41 | 42 | void Space_pio::update (bool host, mword idx, mword attr) 43 | { 44 | mword *m = static_cast(Buddy::phys_to_ptr (walk (host, idx))); 45 | 46 | if (attr) 47 | Atomic::clr_mask (*m, idx_to_mask (idx)); 48 | else 49 | Atomic::set_mask (*m, idx_to_mask (idx)); 50 | } 51 | 52 | void Space_pio::update (Mdb *mdb, mword r) 53 | { 54 | assert (this == mdb->space && this != &Pd::kern); 55 | 56 | Lock_guard guard (mdb->node_lock); 57 | 58 | if (mdb->node_sub & 2) 59 | for (unsigned long i = 0; i < (1UL << mdb->node_order); i++) 60 | update (false, mdb->node_base + i, mdb->node_attr & ~r); 61 | 62 | for (unsigned long i = 0; i < (1UL << mdb->node_order); i++) 63 | update (true, mdb->node_base + i, mdb->node_attr & ~r); 64 | } 65 | 66 | void Space_pio::page_fault (mword addr, mword error) 67 | { 68 | assert (!(error & Hpt::ERR_W)); 69 | 70 | for (; !Pd::current->Space_mem::loc[Cpu::id].sync_from (Pd::current->Space_mem::hpt, addr, CPU_LOCAL);) 71 | Pd::current->Space_mem::replace (addr, reinterpret_cast(&FRAME_1) | Hpt::HPT_NX | Hpt::HPT_A | Hpt::HPT_P); 72 | } 73 | -------------------------------------------------------------------------------- /src/string.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * String Functions 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #define inline 20 | #include "string.hpp" 21 | -------------------------------------------------------------------------------- /src/svm.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Secure Virtual Machine (SVM) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * This file is part of the NOVA microhypervisor. 8 | * 9 | * NOVA is free software: you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as 11 | * published by the Free Software Foundation. 12 | * 13 | * NOVA is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License version 2 for more details. 17 | */ 18 | 19 | #include "cmdline.hpp" 20 | #include "cpu.hpp" 21 | #include "hip.hpp" 22 | #include "msr.hpp" 23 | #include "stdio.hpp" 24 | #include "svm.hpp" 25 | 26 | Paddr Vmcb::root; 27 | unsigned Vmcb::asid_ctr; 28 | uint32 Vmcb::svm_version; 29 | uint32 Vmcb::svm_feature; 30 | 31 | Vmcb::Vmcb (mword bmp, mword nptp) : base_io (bmp), asid (++asid_ctr), int_control (1ul << 24), npt_cr3 (nptp), efer (Cpu::EFER_SVME), g_pat (0x7040600070406ull) 32 | { 33 | base_msr = Buddy::ptr_to_phys (Buddy::allocator.alloc (1, Buddy::FILL_1)); 34 | } 35 | 36 | void Vmcb::init() 37 | { 38 | if (!Cpu::feature (Cpu::FEAT_SVM)) { 39 | Hip::remove (Hip::FEAT_SVM); 40 | return; 41 | } 42 | 43 | if (Cmdline::vtlb) 44 | svm_feature &= ~1; 45 | 46 | Msr::write (Msr::IA32_EFER, Msr::read(Msr::IA32_EFER) | Cpu::EFER_SVME); 47 | Msr::write (Msr::AMD_SVM_HSAVE_PA, root = Buddy::ptr_to_phys (new Vmcb)); 48 | 49 | trace (TRACE_SVM, "VMCB:%#010lx REV:%#x NPT:%u", root, svm_version, has_npt()); 50 | } 51 | -------------------------------------------------------------------------------- /src/tss.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Task State Segment (TSS) 3 | * 4 | * Copyright (C) 2009-2011 Udo Steinberg 5 | * Economic rights: Technische Universitaet Dresden (Germany) 6 | * 7 | * Copyright (C) 2012 Udo Steinberg, Intel Corporation. 8 | * 9 | * This file is part of the NOVA microhypervisor. 10 | * 11 | * NOVA is free software: you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License version 2 as 13 | * published by the Free Software Foundation. 14 | * 15 | * NOVA is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License version 2 for more details. 19 | */ 20 | 21 | #include "hpt.hpp" 22 | #include "tss.hpp" 23 | 24 | ALIGNED(8) Tss Tss::run; 25 | ALIGNED(8) Tss Tss::dbf; 26 | 27 | void Tss::build() 28 | { 29 | #ifdef __i386__ 30 | extern char tss_handler; 31 | dbf.cr3 = Hpt::current(); 32 | dbf.eip = reinterpret_cast(&tss_handler); 33 | dbf.esp = CPU_LOCAL_STCK + PAGE_SIZE; 34 | dbf.eflags = 2; 35 | dbf.cs = SEL_KERN_CODE; 36 | dbf.ds = SEL_KERN_DATA; 37 | dbf.es = SEL_KERN_DATA; 38 | dbf.ss = SEL_KERN_DATA; 39 | run.ss0 = SEL_KERN_DATA; 40 | #endif 41 | 42 | run.sp0 = CPU_LOCAL_STCK + PAGE_SIZE; 43 | run.iobm = static_cast(SPC_LOCAL_IOP - reinterpret_cast(&run)); 44 | } 45 | --------------------------------------------------------------------------------