diff --git a/repos/os/src/drivers/gpu/intel/allocator_guard.h b/repos/os/src/drivers/gpu/intel/allocator_guard.h
deleted file mode 100644
index 2359f9e360..0000000000
--- a/repos/os/src/drivers/gpu/intel/allocator_guard.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * \brief A guard for arbitrary allocators to limit memory exhaustion
- * \author Stefan Kalkowski
- * \date 2010-08-20
- */
-
-/*
- * Copyright (C) 2010-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _ALLOCATOR_GUARD_H_
-#define _ALLOCATOR_GUARD_H_
-
-#include
-#include
-
-namespace Genode { class Allocator_guard; }
-
-
-/**
- * This class acts as guard for arbitrary allocators to limit
- * memory exhaustion
- */
-class Genode::Allocator_guard : public Allocator
-{
- private:
-
- Allocator *_allocator; /* allocator to guard */
- size_t _amount; /* total amount */
- size_t _consumed; /* already consumed bytes */
-
- /*
- * Noncopyable
- */
- Allocator_guard(Allocator_guard const &);
- Allocator_guard &operator = (Allocator_guard const &);
-
- public:
-
- Allocator_guard(Allocator *allocator, size_t amount)
- : _allocator(allocator), _amount(amount), _consumed(0) { }
-
- /**
- * Extend allocation limit
- */
- void upgrade(size_t additional_amount) {
- _amount += additional_amount; }
-
- /**
- * Consume bytes without actually allocating them
- */
- bool withdraw(size_t size)
- {
- if ((_amount - _consumed) < size)
- return false;
-
- _consumed += size;
- return true;
- }
-
- /*************************
- ** Allocator interface **
- *************************/
-
- /**
- * Allocate block
- *
- * \param size block size to allocate
- * \param out_addr resulting pointer to the new block,
- * undefined in the error case
- * \return true on success
- */
- bool alloc(size_t size, void **out_addr) override
- {
- if ((_amount - _consumed) < (size + _allocator->overhead(size)))
- return false;
-
- bool const b = _allocator->alloc(size, out_addr);
- if (b)
- _consumed += size + _allocator->overhead(size);
- return b;
- }
-
- /**
- * Free block a previously allocated block
- */
- void free(void *addr, size_t size) override
- {
- _allocator->free(addr, size);
- _consumed -= size + _allocator->overhead(size);
- }
-
- /**
- * Return amount of backing store consumed by the allocator
- */
- size_t consumed() const override { return _consumed; }
-
- /**
- * Return allocation limit
- */
- size_t quota() const { return _amount; }
-
- /**
- * Return meta-data overhead per block
- */
- size_t overhead(size_t size) const override { return _allocator->overhead(size); }
-
- bool need_size_for_free() const override {
- return _allocator->need_size_for_free(); }
-};
-
-#endif /* _ALLOCATOR_GUARD_H_ */
diff --git a/repos/os/src/drivers/gpu/intel/main.cc b/repos/os/src/drivers/gpu/intel/main.cc
index 52a7123ed4..bb6b82162a 100644
--- a/repos/os/src/drivers/gpu/intel/main.cc
+++ b/repos/os/src/drivers/gpu/intel/main.cc
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -33,7 +34,6 @@
#include
/* local includes */
-#include
#include
#include
#include
@@ -43,6 +43,9 @@
#include
+using namespace Genode;
+
+
namespace Igd {
struct Device_info;
@@ -79,8 +82,8 @@ struct Igd::Device
struct Already_scheduled : Genode::Exception { };
struct Could_not_map_buffer : Genode::Exception { };
- Genode::Env &_env;
- Genode::Allocator_guard _md_alloc;
+ Env &_env;
+ Allocator &_md_alloc;
/***********
** Timer **
@@ -158,39 +161,18 @@ struct Igd::Device
Pci_backend_alloc(Platform::Connection &pci) : _pci(pci) { }
- Genode::Ram_dataspace_capability alloc(Genode::Allocator_guard &guard,
- Genode::size_t size) override
+ Ram_dataspace_capability alloc(size_t size) override
{
- if (!guard.withdraw(size)) { throw Out_of_ram(); }
-
- /*
- * XXX we do not account for any metadata the Platform
- * driver might allocate on our behalf which will
- * make the alloc_dma_buffer call fail.
- */
- _pci.upgrade_ram(size);
- try {
- return _pci.with_upgrade([&] () {
- return _pci.alloc_dma_buffer(size, Genode::UNCACHED); });
- }
- catch (Platform::Out_of_ram) {
- throw Out_of_ram(); }
+ return _pci.with_upgrade([&] () {
+ return _pci.alloc_dma_buffer(size, Genode::UNCACHED); });
}
- void free(Genode::Allocator_guard &guard, Genode::Ram_dataspace_capability cap) override
+ void free(Ram_dataspace_capability cap) override
{
if (!cap.valid()) {
Genode::error("could not free, capability invalid");
return;
}
- size_t const size = Genode::Dataspace_client(cap).size();
- /*
- * XXX we will leak quota because the Platform session is not
- * able to give us back any quota
- */
- guard.upgrade(size);
- Genode::warning("leaking ", size, " bytes of RAM quota at ",
- " platform_drv but upgrade guard anyway");
_pci.free_dma_buffer(cap);
}
@@ -314,22 +296,20 @@ struct Igd::Device
struct Unaligned_size : Genode::Exception { };
- Genode::Ram_dataspace_capability _alloc_dataspace(Genode::Allocator_guard &guard,
- size_t const size)
+ Ram_dataspace_capability _alloc_dataspace(size_t const size)
{
if (size & 0xfff) { throw Unaligned_size(); }
- Genode::Ram_dataspace_capability ds = _pci_backend_alloc.alloc(guard, size);
+ Genode::Ram_dataspace_capability ds = _pci_backend_alloc.alloc(size);
if (!ds.valid()) { throw Out_of_ram(); }
return ds;
}
- void _free_dataspace(Genode::Allocator_guard &guard,
- Genode::Ram_dataspace_capability cap)
+ void _free_dataspace(Ram_dataspace_capability const cap)
{
if (!cap.valid()) { return; }
- _pci_backend_alloc.free(guard, cap);
+ _pci_backend_alloc.free(cap);
}
struct Ggtt_mmio_mapping : Ggtt::Mapping
@@ -566,12 +546,12 @@ struct Igd::Device
}
template
- Engine *_alloc_engine(Genode::Allocator_guard &md_alloc, uint32_t const id)
+ Engine *_alloc_engine(Allocator &md_alloc, uint32_t const id)
{
/* alloc context memory */
size_t const ctx_offset = _ggtt->find_free(CONTEXT::CONTEXT_PAGES, true);
size_t const ctx_size = CONTEXT::CONTEXT_PAGES * PAGE_SIZE;
- Ram ctx_ds = _alloc_dataspace(md_alloc, ctx_size);
+ Ram ctx_ds = _alloc_dataspace(ctx_size);
Ggtt::Mapping const &ctx_map = _map_dataspace_ggtt(md_alloc, ctx_ds, ctx_offset);
addr_t const ctx_vaddr = (addr_t)_env.rm().attach(ctx_map.cap) + PAGE_SIZE /* omit GuC page */;
addr_t const ctx_gmaddr = (ctx_offset + 1 /* omit GuC page */) * PAGE_SIZE;
@@ -579,17 +559,17 @@ struct Igd::Device
/* alloc ring memory */
size_t const ring_offset = _ggtt->find_free(Rcs_context::RING_PAGES, true);
size_t const ring_size = CONTEXT::RING_PAGES * PAGE_SIZE;
- Ram ring_ds = _alloc_dataspace(md_alloc, ring_size);
+ Ram ring_ds = _alloc_dataspace(ring_size);
Ggtt::Mapping const &ring_map = _map_dataspace_ggtt(md_alloc, ring_ds, ring_offset);
addr_t const ring_vaddr = _env.rm().attach(ring_map.cap);
addr_t const ring_gmaddr = ring_offset * PAGE_SIZE;
/* PPGTT */
Igd::Ppgtt_allocator *ppgtt_allocator =
- new (&md_alloc) Igd::Ppgtt_allocator(_env.rm(), md_alloc, _pci_backend_alloc);
+ new (&md_alloc) Igd::Ppgtt_allocator(_env.rm(), _pci_backend_alloc);
Igd::Ppgtt_scratch *scratch =
- new (&md_alloc) Igd::Ppgtt_scratch(md_alloc, _pci_backend_alloc);
+ new (&md_alloc) Igd::Ppgtt_scratch(_pci_backend_alloc);
_populate_scratch(scratch);
Igd::Ppgtt *ppgtt =
@@ -606,7 +586,7 @@ struct Igd::Device
}
template
- void _free_engine(Genode::Allocator_guard &md_alloc, Engine *engine)
+ void _free_engine(Allocator &md_alloc, Engine *engine)
{
/* free PPGTT */
Genode::destroy(&md_alloc, engine->ppgtt_scratch);
@@ -616,13 +596,13 @@ struct Igd::Device
{
_env.rm().detach(engine->ring_vaddr);
_unmap_dataspace_ggtt(md_alloc, engine->ring_map.cap);
- _free_dataspace(md_alloc, engine->ring_ds);
+ _free_dataspace(engine->ring_ds);
}
/* free context memory */
{
_env.rm().detach(engine->ctx_vaddr - PAGE_SIZE);
_unmap_dataspace_ggtt(md_alloc, engine->ctx_map.cap);
- _free_dataspace(md_alloc, engine->ctx_ds);
+ _free_dataspace(engine->ctx_ds);
}
/* free engine */
Genode::destroy(&md_alloc, engine);
@@ -820,25 +800,23 @@ struct Igd::Device
}
};
- Vgpu* _alloc_vgpu(Genode::Allocator_guard &md_alloc)
+ Vgpu* _alloc_vgpu(Allocator &alloc)
{
uint32_t const id = _id_alloc();
- Engine *rcs = _alloc_engine(md_alloc, id);
+ Engine *rcs = _alloc_engine(alloc, id);
- Vgpu *gpu = new (&md_alloc) Vgpu(id, *rcs);
+ Vgpu *gpu = new (&alloc) Vgpu(id, *rcs);
_vgpu_avail--;
return gpu;
}
- void _free_vgpu(Genode::Allocator_guard &md_alloc, Vgpu *vgpu)
+ void _free_vgpu(Allocator &md_alloc, Vgpu &vgpu)
{
- if (!vgpu) { return; }
-
- Engine *rcs = &vgpu->rcs;
+ Engine *rcs = &vgpu.rcs;
_free_engine(md_alloc, rcs);
- Genode::destroy(&md_alloc, vgpu);
+ Genode::destroy(&md_alloc, &vgpu);
_vgpu_avail++;
}
@@ -1068,7 +1046,7 @@ struct Igd::Device
Platform::Device_capability cap,
Genode::Xml_node config)
:
- _env(env), _md_alloc(&alloc, 8192), _pci(pci), _pci_cap(cap)
+ _env(env), _md_alloc(alloc), _pci(pci), _pci_cap(cap)
{
using namespace Genode;
@@ -1111,7 +1089,7 @@ struct Igd::Device
config.attribute_value("fb_size", 32u<<20);
log("Reserve beginning ", fb_size, " in GGTT for framebuffer");
- Ram_dataspace_capability scratch_page_ds = _pci_backend_alloc.alloc(_md_alloc, PAGE_SIZE);
+ Ram_dataspace_capability scratch_page_ds = _pci_backend_alloc.alloc(PAGE_SIZE);
addr_t const scratch_page = Dataspace_client(scratch_page_ds).phys_addr();
size_t const ggtt_size = (1u << MGGC_0_2_0_PCI::Gtt_graphics_memory_size::get(v)) << 20;
@@ -1166,7 +1144,7 @@ struct Igd::Device
* \throw Out_of_ram
* \throw Out_of_caps
*/
- Vgpu& alloc_vgpu(Genode::Allocator_guard &alloc)
+ Vgpu& alloc_vgpu(Allocator &alloc)
{
return *_alloc_vgpu(alloc);
}
@@ -1177,9 +1155,9 @@ struct Igd::Device
* \param alloc reference to resource allocator
* \param vgpu reference to vGPU
*/
- void free_vgpu(Genode::Allocator_guard &alloc, Vgpu &vgpu)
+ void free_vgpu(Allocator &alloc, Vgpu &vgpu)
{
- _free_vgpu(alloc, &vgpu);
+ _free_vgpu(alloc, vgpu);
}
/**
@@ -1238,10 +1216,10 @@ struct Igd::Device
*
* \throw Out_of_memory
*/
- Genode::Dataspace_capability alloc_buffer(Genode::Allocator_guard &guard,
- size_t size)
+ Genode::Dataspace_capability alloc_buffer(Allocator &,
+ size_t const size)
{
- return _pci_backend_alloc.alloc(guard, size);
+ return _pci_backend_alloc.alloc(size);
}
/**
@@ -1250,13 +1228,12 @@ struct Igd::Device
* \param guard resource allocator and guard
* \param cap DMA buffer capability
*/
- void free_buffer(Genode::Allocator_guard &guard,
- Genode::Dataspace_capability cap)
+ void free_buffer(Allocator &,
+ Dataspace_capability const cap)
{
if (!cap.valid()) { return; }
- _pci_backend_alloc.free(guard,
- Genode::static_cap_cast(cap));
+ _pci_backend_alloc.free(Genode::static_cap_cast(cap));
}
/**
@@ -1354,7 +1331,8 @@ class Gpu::Session_component : public Genode::Session_object
private:
Genode::Region_map &_rm;
- Genode::Allocator_guard _guard;
+ Constrained_ram_allocator _ram;
+ Heap _heap { _ram, _rm };
Igd::Device &_device;
Igd::Device::Vgpu &_vgpu;
@@ -1385,7 +1363,7 @@ class Gpu::Session_component : public Genode::Session_object
auto lookup_and_free = [&] (Buffer &buffer) {
if (buffer.map.offset != Igd::Ggtt::Mapping::INVALID_OFFSET) {
- _device.unmap_buffer(_guard, buffer.map);
+ _device.unmap_buffer(_heap, buffer.map);
}
if (buffer.fenced != Buffer::INVALID_FENCE) {
@@ -1397,8 +1375,8 @@ class Gpu::Session_component : public Genode::Session_object
Genode::size_t const actual_size = buf.size();
_vgpu.rcs_unmap_ppgtt(buffer.ppgtt_va, actual_size);
- _device.free_buffer(_guard, buffer.cap);
- Genode::destroy(&_guard, &buffer);
+ _device.free_buffer(_heap, buffer.cap);
+ Genode::destroy(&_heap, &buffer);
};
_buffer_registry.for_each(lookup_and_free);
}
@@ -1413,35 +1391,30 @@ class Gpu::Session_component : public Genode::Session_object
* \param ram_quota initial ram quota
* \param device reference to the physical device
*/
- Session_component(Genode::Entrypoint &ep,
- Resources resources,
- Label const &label,
- Diag diag,
- Genode::Region_map &rm,
- Genode::Allocator &md_alloc,
- Genode::size_t ram_quota,
- Igd::Device &device)
+ Session_component(Entrypoint &ep,
+ Ram_allocator &ram,
+ Region_map &rm,
+ Resources resources,
+ Label const &label,
+ Diag diag,
+ Igd::Device &device)
:
Session_object(ep, resources, label, diag),
- _rm(rm), _guard(&md_alloc, ram_quota),
- _device(device), _vgpu(_device.alloc_vgpu(_guard))
+ _rm(rm),
+ _ram(ram, _ram_quota_guard(), _cap_quota_guard()),
+ _device(device), _vgpu(_device.alloc_vgpu(_heap))
{ }
~Session_component()
{
_free_buffers();
- _device.free_vgpu(_guard, _vgpu);
+ _device.free_vgpu(_heap, _vgpu);
}
/*********************************
** Session_component interface **
*********************************/
- void upgrade_ram_quota(Genode::size_t quota)
- {
- _guard.upgrade(quota);
- }
-
bool vgpu_active() const
{
return _device.vgpu_active(_vgpu);
@@ -1506,17 +1479,14 @@ class Gpu::Session_component : public Genode::Session_object
/* roundup to next page size and add guarding page */
size = ((size + 0xffful) & ~0xffful) + 0x1000;
- Genode::size_t const need = size + sizeof(Genode::Registered);
- Genode::size_t const avail = _guard.quota() - _guard.consumed();
- if (need > avail) { throw Gpu::Session_component::Out_of_ram(); }
-
try {
- Genode::Dataspace_capability cap = _device.alloc_buffer(_guard, size);
+ Genode::Dataspace_capability cap = _device.alloc_buffer(_heap, size);
try {
- new (&_guard) Genode::Registered(_buffer_registry, cap);
- } catch(...) {
- _device.free_buffer(_guard, cap);
+ new (&_heap) Genode::Registered(_buffer_registry, cap);
+ } catch (...) {
+ if (cap.valid())
+ _device.free_buffer(_heap, cap);
throw Gpu::Session_component::Out_of_ram();
}
return cap;
@@ -1539,8 +1509,8 @@ class Gpu::Session_component : public Genode::Session_object
/* XXX throw */
}
- _device.free_buffer(_guard, cap);
- Genode::destroy(&_guard, &buffer);
+ _device.free_buffer(_heap, cap);
+ Genode::destroy(&_heap, &buffer);
};
_buffer_registry.for_each(lookup_and_free);
}
@@ -1561,7 +1531,7 @@ class Gpu::Session_component : public Genode::Session_object
}
try {
- Igd::Ggtt::Mapping const &map = _device.map_buffer(_guard, cap, aperture);
+ Igd::Ggtt::Mapping const &map = _device.map_buffer(_heap, cap, aperture);
buffer.map.cap = map.cap;
buffer.map.offset = map.offset;
map_cap = buffer.map.cap;
@@ -1589,7 +1559,7 @@ class Gpu::Session_component : public Genode::Session_object
_vgpu.active_fences--;
}
- _device.unmap_buffer(_guard, buffer.map);
+ _device.unmap_buffer(_heap, buffer.map);
buffer.map.offset = Igd::Ggtt::Mapping::INVALID_OFFSET;
unmapped = true;
};
@@ -1736,23 +1706,18 @@ class Gpu::Root : public Gpu::Root_component
using namespace Genode;
return new (md_alloc())
- Session_component(_env.ep(),
+ Session_component(_env.ep(), _env.ram(), _env.rm(),
session_resources_from_args(args),
session_label_from_args(args),
session_diag_from_args(args),
- _env.rm(), *md_alloc(), ram_quota,
*_device);
} catch (...) { throw; }
}
- void _upgrade_session(Session_component *s, char const *args) override
+ void _upgrade_session(Session_component *s, const char *args) override
{
- s->upgrade_ram_quota(_ram_quota(args));
-
- /*
- s->Ram_quota_guard::upgrade(ram_quota_from_args(args));
- s->Cap_quota_guard::upgrade(cap_quota_from_args(args));
- */
+ s->upgrade(ram_quota_from_args(args));
+ s->upgrade(cap_quota_from_args(args));
}
void _destroy_session(Session_component *s) override
diff --git a/repos/os/src/drivers/gpu/intel/ppgtt.h b/repos/os/src/drivers/gpu/intel/ppgtt.h
index ca1f1749d5..d52c2a8663 100644
--- a/repos/os/src/drivers/gpu/intel/ppgtt.h
+++ b/repos/os/src/drivers/gpu/intel/ppgtt.h
@@ -150,8 +150,7 @@ namespace Genode
{
private:
- Genode::Allocator_guard &_guard;
- Utils::Backend_alloc &_backend;
+ Utils::Backend_alloc &_backend;
public:
@@ -174,32 +173,31 @@ namespace Genode
Page pd { };
Page pdp { };
- Scratch(Genode::Allocator_guard &guard,
- Utils::Backend_alloc &backend)
+ Scratch(Utils::Backend_alloc &backend)
:
- _guard(guard), _backend(backend)
+ _backend(backend)
{
/* XXX addr PAT helper instead of hardcoding */
- page.ds = _backend.alloc(_guard, PAGE_SIZE);
+ page.ds = _backend.alloc(PAGE_SIZE);
page.addr = Genode::Dataspace_client(page.ds).phys_addr();
page.addr |= 1;
page.addr |= 1 << 1;
page.next = nullptr;
- pt.ds = _backend.alloc(_guard, PAGE_SIZE);
+ pt.ds = _backend.alloc(PAGE_SIZE);
pt.addr = Genode::Dataspace_client(pt.ds).phys_addr();
pt.addr |= 1;
pt.addr |= 1 << 1;
pt.addr |= 1 << 7;
pt.next = &page;
- pd.ds = _backend.alloc(_guard, PAGE_SIZE);
+ pd.ds = _backend.alloc(PAGE_SIZE);
pd.addr = Genode::Dataspace_client(pd.ds).phys_addr();
pd.addr |= 1;
pd.addr |= 1 << 1;
pd.next = &pt;
- pdp.ds = _backend.alloc(_guard, PAGE_SIZE);
+ pdp.ds = _backend.alloc(PAGE_SIZE);
pdp.addr = Genode::Dataspace_client(pdp.ds).phys_addr();
pdp.addr |= 1;
pdp.addr |= 1 << 1;
@@ -208,10 +206,10 @@ namespace Genode
virtual ~Scratch()
{
- _backend.free(_guard, pdp.ds);
- _backend.free(_guard, pd.ds);
- _backend.free(_guard, pt.ds);
- _backend.free(_guard, page.ds);
+ _backend.free(pdp.ds);
+ _backend.free(pd.ds);
+ _backend.free(pt.ds);
+ _backend.free(page.ds);
}
};
}
@@ -832,9 +830,8 @@ struct Igd::Ppgtt : public Genode::Pml4_table
*/
struct Igd::Ppgtt_scratch : public Genode::Scratch
{
- Ppgtt_scratch(Genode::Allocator_guard &guard,
- Utils::Backend_alloc &backend)
- : Scratch(guard, backend) { }
+ Ppgtt_scratch(Utils::Backend_alloc &backend)
+ : Scratch(backend) { }
};
#endif /* _PPGTT_H_ */
diff --git a/repos/os/src/drivers/gpu/intel/ppgtt_allocator.h b/repos/os/src/drivers/gpu/intel/ppgtt_allocator.h
index 7789fe075e..0ef1b23cdf 100644
--- a/repos/os/src/drivers/gpu/intel/ppgtt_allocator.h
+++ b/repos/os/src/drivers/gpu/intel/ppgtt_allocator.h
@@ -17,7 +17,6 @@
/* local includes */
#include
#include
-#include
namespace Igd {
@@ -31,7 +30,6 @@ class Igd::Ppgtt_allocator : public Genode::Translation_table_allocator
private:
Genode::Region_map &_rm;
- Genode::Allocator_guard &_guard;
Utils::Backend_alloc &_backend;
enum { ELEMENTS = 256, };
@@ -40,9 +38,8 @@ class Igd::Ppgtt_allocator : public Genode::Translation_table_allocator
public:
Ppgtt_allocator(Genode::Region_map &rm,
- Genode::Allocator_guard &guard,
Utils::Backend_alloc &backend)
- : _rm(rm), _guard(guard), _backend(backend) { }
+ : _rm(rm), _backend(backend) { }
/*************************
** Allocator interface **
@@ -50,7 +47,7 @@ class Igd::Ppgtt_allocator : public Genode::Translation_table_allocator
bool alloc(size_t size, void **out_addr) override
{
- Genode::Ram_dataspace_capability ds = _backend.alloc(_guard, size);
+ Genode::Ram_dataspace_capability ds = _backend.alloc(size);
if (!ds.valid()) { return false; }
*out_addr = _rm.attach(ds);
@@ -68,7 +65,7 @@ class Igd::Ppgtt_allocator : public Genode::Translation_table_allocator
}
_rm.detach(addr);
- _backend.free(_guard, cap);
+ _backend.free(cap);
}
bool need_size_for_free() const override { return false; }
diff --git a/repos/os/src/drivers/gpu/intel/utils.h b/repos/os/src/drivers/gpu/intel/utils.h
index 8ddd17abbe..eeb87b5ad5 100644
--- a/repos/os/src/drivers/gpu/intel/utils.h
+++ b/repos/os/src/drivers/gpu/intel/utils.h
@@ -29,8 +29,8 @@ namespace Utils {
*/
struct Backend_alloc : Genode::Interface
{
- virtual Ram alloc(Genode::Allocator_guard &, Genode::size_t) = 0;
- virtual void free(Genode::Allocator_guard &, Ram) = 0;
+ virtual Ram alloc(Genode::size_t) = 0;
+ virtual void free(Ram) = 0;
};
template class Address_map;