54 lines
1.7 KiB
C++
54 lines
1.7 KiB
C++
/*
|
|
* Memory-Mapped I/O
|
|
*
|
|
* Copyright (C) 2019-2025 Udo Steinberg, BlueRock Security, Inc.
|
|
*
|
|
* This file is part of the NOVA microhypervisor.
|
|
*
|
|
* NOVA is free software: you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* NOVA is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License version 2 for more details.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "ptab_hpt.hpp"
|
|
#include "space_hst.hpp"
|
|
|
|
class Mmio
|
|
{
|
|
private:
|
|
static inline constinit Atomic<uintptr_t> mmio_base { MMAP_GLB_MMIO };
|
|
|
|
protected:
|
|
uintptr_t const phys; // Phys Base
|
|
uintptr_t const mmio; // MMIO Base
|
|
|
|
static auto alloc_mmio (uintptr_t const phys, size_t const size)
|
|
{
|
|
// Round physical address and size to full pages
|
|
auto p { aligned_dn (Hpt::page_size (0), phys) };
|
|
auto s { aligned_up (Hpt::page_size (0), phys + size) - p };
|
|
|
|
// Reserve physical memory region
|
|
Space_hst::access_ctrl (p, s, Paging::NONE);
|
|
|
|
// Allocate MMIO region
|
|
auto v { mmio_base.fetch_add (s) };
|
|
auto r { v | (phys & Hpt::offs_mask (0)) };
|
|
|
|
// Map MMIO region
|
|
for (unsigned o; s; s -= BITN (o), p += BITN (o), v += BITN (o))
|
|
Hptp::master_map (v, p, (o = aligned_order (s, p, v)) - PAGE_BITS, Paging::Permissions (Paging::G | Paging::W | Paging::R), Memattr::dev());
|
|
|
|
return r;
|
|
}
|
|
|
|
explicit Mmio (uintptr_t p, size_t s) : phys { p }, mmio { alloc_mmio (p, s) } {}
|
|
};
|