mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-25 00:11:07 +00:00
parent
833c9e01f5
commit
c77f146e72
@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2015 Genode Labs GmbH
|
* Copyright (C) 2009-2016 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
/* base includes */
|
/* base includes */
|
||||||
#include <io_mem_session/connection.h>
|
#include <io_mem_session/connection.h>
|
||||||
|
#include <util/misc_math.h>
|
||||||
#include <util/mmio.h>
|
#include <util/mmio.h>
|
||||||
|
|
||||||
/* os includes */
|
/* os includes */
|
||||||
@ -137,10 +138,10 @@ struct Dmar_struct_header : Generic
|
|||||||
} while (addr < dmar_entry_end());
|
} while (addr < dmar_entry_end());
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Dmar_struct_header * clone()
|
struct Dmar_struct_header * clone(Genode::Allocator &alloc)
|
||||||
{
|
{
|
||||||
size_t const size = dmar_entry_end() - reinterpret_cast<addr_t>(this);
|
size_t const size = dmar_entry_end() - reinterpret_cast<addr_t>(this);
|
||||||
char * clone = new (env()->heap()) char[size];
|
char * clone = new (&alloc) char[size];
|
||||||
memcpy(clone, this, size);
|
memcpy(clone, this, size);
|
||||||
|
|
||||||
return reinterpret_cast<Dmar_struct_header *>(clone);
|
return reinterpret_cast<Dmar_struct_header *>(clone);
|
||||||
@ -371,7 +372,7 @@ class Table_wrapper
|
|||||||
/**
|
/**
|
||||||
* Parse override structures
|
* Parse override structures
|
||||||
*/
|
*/
|
||||||
void parse_madt()
|
void parse_madt(Genode::Allocator &alloc)
|
||||||
{
|
{
|
||||||
Apic_struct *apic = _table->apic_struct();
|
Apic_struct *apic = _table->apic_struct();
|
||||||
for (; apic < _table->end(); apic = apic->next()) {
|
for (; apic < _table->end(); apic = apic->next()) {
|
||||||
@ -382,12 +383,12 @@ class Table_wrapper
|
|||||||
|
|
||||||
PINF("MADT IRQ %u -> GSI %u flags: %x", o->irq, o->gsi, o->flags);
|
PINF("MADT IRQ %u -> GSI %u flags: %x", o->irq, o->gsi, o->flags);
|
||||||
|
|
||||||
Irq_override::list()->insert(new (env()->heap())
|
Irq_override::list()->insert(new (&alloc)
|
||||||
Irq_override(o->irq, o->gsi, o->flags));
|
Irq_override(o->irq, o->gsi, o->flags));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_mcfg() const
|
void parse_mcfg(Genode::Allocator &alloc) const
|
||||||
{
|
{
|
||||||
Mcfg_struct *mcfg = _table->mcfg_struct();
|
Mcfg_struct *mcfg = _table->mcfg_struct();
|
||||||
for (; mcfg < _table->mcfg_end(); mcfg = mcfg->next()) {
|
for (; mcfg < _table->mcfg_end(); mcfg = mcfg->next()) {
|
||||||
@ -400,11 +401,11 @@ class Table_wrapper
|
|||||||
uint32_t bus_start = mcfg->pci_bus_start * 32 * 8;
|
uint32_t bus_start = mcfg->pci_bus_start * 32 * 8;
|
||||||
|
|
||||||
Pci_config_space::list()->insert(
|
Pci_config_space::list()->insert(
|
||||||
new (env()->heap()) Pci_config_space(bus_start, func_count, mcfg->base));
|
new (&alloc) Pci_config_space(bus_start, func_count, mcfg->base));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_dmar() const
|
void parse_dmar(Genode::Allocator &alloc) const
|
||||||
{
|
{
|
||||||
Dmar_struct_header *head = _table->dmar_header();
|
Dmar_struct_header *head = _table->dmar_header();
|
||||||
PLOG("%u bit DMA physical addressable%s\n", head->width + 1,
|
PLOG("%u bit DMA physical addressable%s\n", head->width + 1,
|
||||||
@ -415,7 +416,7 @@ class Table_wrapper
|
|||||||
PLOG("DMA remapping structure type=%u", dmar.read<Dmar_common::Type>());
|
PLOG("DMA remapping structure type=%u", dmar.read<Dmar_common::Type>());
|
||||||
});
|
});
|
||||||
|
|
||||||
Dmar_entry::list()->insert(new (env()->heap()) Dmar_entry(head->clone()));
|
Dmar_entry::list()->insert(new (&alloc) Dmar_entry(head->clone(alloc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Table_wrapper(addr_t base) : _base(base), _table(0)
|
Table_wrapper(addr_t base) : _base(base), _table(0)
|
||||||
@ -487,14 +488,14 @@ class Element : public List<Element>::Element
|
|||||||
uint8_t _type; /* the type of this element */
|
uint8_t _type; /* the type of this element */
|
||||||
uint32_t _size; /* size in bytes */
|
uint32_t _size; /* size in bytes */
|
||||||
uint32_t _size_len; /* length of size in bytes */
|
uint32_t _size_len; /* length of size in bytes */
|
||||||
char *_name; /* name of element */
|
char _name[64]; /* name of element */
|
||||||
uint32_t _name_len; /* length of name in bytes */
|
uint32_t _name_len; /* length of name in bytes */
|
||||||
uint32_t _bdf; /* bus device function */
|
uint32_t _bdf; /* bus device function */
|
||||||
uint8_t const *_data; /* pointer to the data section */
|
uint8_t const *_data; /* pointer to the data section */
|
||||||
uint32_t _para_len; /* parameters to be skipped */
|
uint32_t _para_len; /* parameters to be skipped */
|
||||||
bool _valid; /* true if this is a valid element */
|
bool _valid; /* true if this is a valid element */
|
||||||
bool _routed; /* has the PCI information been read */
|
bool _routed; /* has the PCI information been read */
|
||||||
List<Pci_routing> *_pci; /* list of PCI routing elements for this element */
|
List<Pci_routing> _pci; /* list of PCI routing elements for this element */
|
||||||
|
|
||||||
/* packages we are looking for */
|
/* packages we are looking for */
|
||||||
enum { DEVICE = 0x5b, SUB_DEVICE = 0x82, DEVICE_NAME = 0x8, SCOPE = 0x10, METHOD = 0x14, PACKAGE_OP = 0x12 };
|
enum { DEVICE = 0x5b, SUB_DEVICE = 0x82, DEVICE_NAME = 0x8, SCOPE = 0x10, METHOD = 0x14, PACKAGE_OP = 0x12 };
|
||||||
@ -655,8 +656,7 @@ class Element : public List<Element>::Element
|
|||||||
|
|
||||||
/* is absolute name */
|
/* is absolute name */
|
||||||
if (*name == ROOT_PREFIX || !parent) {
|
if (*name == ROOT_PREFIX || !parent) {
|
||||||
_name = (char *)env()->heap()->alloc(_name_len);
|
memcpy(_name, name + prefix_len, min(sizeof(_name), _name_len));
|
||||||
memcpy(_name, name + prefix_len, _name_len);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* skip parts */
|
/* skip parts */
|
||||||
@ -665,7 +665,11 @@ class Element : public List<Element>::Element
|
|||||||
|
|
||||||
/* skip parent prefix */
|
/* skip parent prefix */
|
||||||
for (uint32_t p = 0; name[p] == PARENT_PREFIX; p++, parent_len -= NAME_LEN) ;
|
for (uint32_t p = 0; name[p] == PARENT_PREFIX; p++, parent_len -= NAME_LEN) ;
|
||||||
_name = (char *)env()->heap()->alloc(_name_len + parent_len);
|
|
||||||
|
if (_name_len + parent_len > sizeof(_name)) {
|
||||||
|
PERR("name is not large enough");
|
||||||
|
throw -1;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(_name, parent->_name, parent_len);
|
memcpy(_name, parent->_name, parent_len);
|
||||||
memcpy(_name + parent_len, name + prefix_len, _name_len);
|
memcpy(_name + parent_len, name + prefix_len, _name_len);
|
||||||
@ -747,7 +751,7 @@ class Element : public List<Element>::Element
|
|||||||
* Try to locate _PRT table and its GSI values for device
|
* Try to locate _PRT table and its GSI values for device
|
||||||
* (data has to be located within the device data)
|
* (data has to be located within the device data)
|
||||||
*/
|
*/
|
||||||
void _direct_prt(Element *dev)
|
void _direct_prt(Genode::Allocator &alloc, Element *dev)
|
||||||
{
|
{
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
|
|
||||||
@ -771,11 +775,11 @@ class Element : public List<Element>::Element
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i == 4) {
|
if (i == 4) {
|
||||||
Pci_routing * r = new (env()->heap()) Pci_routing(val[0], val[1], val[3]);
|
Pci_routing * r = new (&alloc) Pci_routing(val[0], val[1], val[3]);
|
||||||
|
|
||||||
/* set _ADR, _PIN, _GSI */
|
/* set _ADR, _PIN, _GSI */
|
||||||
dev->pci_list()->insert(r);
|
dev->pci_list().insert(r);
|
||||||
dev->pci_list()->first()->dump();
|
dev->pci_list().first()->dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
len = len ? (e.data() - (_data + offset)) + e.size() : 1;
|
len = len ? (e.data() - (_data + offset)) + e.size() : 1;
|
||||||
@ -785,7 +789,7 @@ class Element : public List<Element>::Element
|
|||||||
/**
|
/**
|
||||||
* Search for _PRT outside of device
|
* Search for _PRT outside of device
|
||||||
*/
|
*/
|
||||||
void _indirect_prt(Element *dev)
|
void _indirect_prt(Genode::Allocator &alloc, Element *dev)
|
||||||
{
|
{
|
||||||
uint32_t name_len;
|
uint32_t name_len;
|
||||||
uint32_t found = 0;
|
uint32_t found = 0;
|
||||||
@ -805,7 +809,7 @@ class Element : public List<Element>::Element
|
|||||||
for (uint32_t skip = 0; skip <= dev->_name_len / NAME_LEN; skip++) {
|
for (uint32_t skip = 0; skip <= dev->_name_len / NAME_LEN; skip++) {
|
||||||
Element *e = dev->_compare(name, skip * NAME_LEN);
|
Element *e = dev->_compare(name, skip * NAME_LEN);
|
||||||
if (e)
|
if (e)
|
||||||
e->_direct_prt(dev);
|
e->_direct_prt(alloc, dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -815,9 +819,11 @@ class Element : public List<Element>::Element
|
|||||||
|
|
||||||
Element(uint8_t const *data = 0, bool package_op4 = false)
|
Element(uint8_t const *data = 0, bool package_op4 = false)
|
||||||
:
|
:
|
||||||
_type(0), _size(0), _size_len(0), _name(0), _name_len(0), _bdf(0),
|
_type(0), _size(0), _size_len(0), _name_len(0), _bdf(0),
|
||||||
_data(data), _para_len(0), _valid(false), _routed(false), _pci(0)
|
_data(data), _para_len(0), _valid(false), _routed(false)
|
||||||
{
|
{
|
||||||
|
_name[0] = '\0';
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -900,18 +906,14 @@ class Element : public List<Element>::Element
|
|||||||
_type = other._type;
|
_type = other._type;
|
||||||
_size = other._size;
|
_size = other._size;
|
||||||
_size_len = other._size_len;
|
_size_len = other._size_len;
|
||||||
|
memcpy(_name, other._name, sizeof(_name));
|
||||||
_name_len = other._name_len;
|
_name_len = other._name_len;
|
||||||
_bdf = other._bdf;
|
_bdf = other._bdf;
|
||||||
_data = other._data;
|
_data = other._data;
|
||||||
|
_para_len = other._para_len;
|
||||||
_valid = other._valid;
|
_valid = other._valid;
|
||||||
_routed = other._routed;
|
_routed = other._routed;
|
||||||
_pci = other._pci;
|
_pci = other._pci;
|
||||||
_para_len = other._para_len;
|
|
||||||
|
|
||||||
if (other._name) {
|
|
||||||
_name = (char *)env()->heap()->alloc(other._name_len);
|
|
||||||
memcpy(_name, other._name, _name_len);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_device_name() { return _type == DEVICE_NAME; }
|
bool is_device_name() { return _type == DEVICE_NAME; }
|
||||||
@ -933,11 +935,7 @@ class Element : public List<Element>::Element
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~Element()
|
virtual ~Element() { }
|
||||||
{
|
|
||||||
if (_name)
|
|
||||||
env()->heap()->free(_name, _name_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accessors
|
* Accessors
|
||||||
@ -969,7 +967,7 @@ class Element : public List<Element>::Element
|
|||||||
return &_list;
|
return &_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clean_list()
|
static void clean_list(Genode::Allocator &alloc)
|
||||||
{
|
{
|
||||||
unsigned long freed_up = 0;
|
unsigned long freed_up = 0;
|
||||||
|
|
||||||
@ -985,7 +983,7 @@ class Element : public List<Element>::Element
|
|||||||
|
|
||||||
Element * next = element->next();
|
Element * next = element->next();
|
||||||
Element::list()->remove(element);
|
Element::list()->remove(element);
|
||||||
destroy(env()->heap(), element);
|
destroy(&alloc, element);
|
||||||
element = next;
|
element = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -996,17 +994,12 @@ class Element : public List<Element>::Element
|
|||||||
/**
|
/**
|
||||||
* Return list of PCI information for this element
|
* Return list of PCI information for this element
|
||||||
*/
|
*/
|
||||||
List<Pci_routing> *pci_list()
|
List<Pci_routing> & pci_list() { return _pci; }
|
||||||
{
|
|
||||||
if (!_pci)
|
|
||||||
_pci = new (env()->heap()) List<Pci_routing>();
|
|
||||||
return _pci;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse elements of table
|
* Parse elements of table
|
||||||
*/
|
*/
|
||||||
static void parse(Generic *table)
|
static void parse(Genode::Allocator &alloc, Generic *table)
|
||||||
{
|
{
|
||||||
uint8_t const *data = table->data();
|
uint8_t const *data = table->data();
|
||||||
for (; data < table->data() + table->size; data++) {
|
for (; data < table->data() + table->size; data++) {
|
||||||
@ -1018,7 +1011,7 @@ class Element : public List<Element>::Element
|
|||||||
if (data + e.size() > table->data() + table->size)
|
if (data + e.size() > table->data() + table->size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Element *i = new (env()->heap()) Element(e);
|
Element *i = new (&alloc) Element(e);
|
||||||
list()->insert(i);
|
list()->insert(i);
|
||||||
|
|
||||||
/* skip header */
|
/* skip header */
|
||||||
@ -1031,13 +1024,13 @@ class Element : public List<Element>::Element
|
|||||||
data += e._para_len;
|
data += e._para_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_bdf();
|
parse_bdf(alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse BDF and GSI information
|
* Parse BDF and GSI information
|
||||||
*/
|
*/
|
||||||
static void parse_bdf()
|
static void parse_bdf(Genode::Allocator &alloc)
|
||||||
{
|
{
|
||||||
for (Element *e = list()->first(); e; e = e->next()) {
|
for (Element *e = list()->first(); e; e = e->next()) {
|
||||||
|
|
||||||
@ -1064,8 +1057,8 @@ class Element : public List<Element>::Element
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
PDBG("Scanning device %x", e->_bdf);
|
PDBG("Scanning device %x", e->_bdf);
|
||||||
|
|
||||||
prt->_direct_prt(e);
|
prt->_direct_prt(alloc, e);
|
||||||
prt->_indirect_prt(e);
|
prt->_indirect_prt(alloc, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
e->_routed = true;
|
e->_routed = true;
|
||||||
@ -1083,7 +1076,7 @@ class Element : public List<Element>::Element
|
|||||||
if (!e->is_device() || e->_bdf != bridge_bdf)
|
if (!e->is_device() || e->_bdf != bridge_bdf)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Pci_routing *r = e->pci_list()->first();
|
Pci_routing *r = e->pci_list().first();
|
||||||
for (; r; r = r->next()) {
|
for (; r; r = r->next()) {
|
||||||
if (r->match_bdf(device_bdf) && r->pin() == pin) {
|
if (r->match_bdf(device_bdf) && r->pin() == pin) {
|
||||||
if (verbose) PDBG("Found GSI: %u device : %x pin %u",
|
if (verbose) PDBG("Found GSI: %u device : %x pin %u",
|
||||||
@ -1104,6 +1097,9 @@ class Acpi_table
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Genode::Env &env;
|
||||||
|
Genode::Allocator &alloc;
|
||||||
|
|
||||||
/* BIOS range to scan for RSDP */
|
/* BIOS range to scan for RSDP */
|
||||||
enum { BIOS_BASE = 0xe0000, BIOS_SIZE = 0x20000 };
|
enum { BIOS_BASE = 0xe0000, BIOS_SIZE = 0x20000 };
|
||||||
|
|
||||||
@ -1118,7 +1114,7 @@ class Acpi_table
|
|||||||
if (!io_ds.valid())
|
if (!io_ds.valid())
|
||||||
throw -1;
|
throw -1;
|
||||||
|
|
||||||
uint8_t *ret = env()->rm_session()->attach(io_ds, size);
|
uint8_t *ret = env.rm().attach(io_ds, size);
|
||||||
cap = io_mem.cap();
|
cap = io_mem.cap();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1146,25 +1142,25 @@ class Acpi_table
|
|||||||
try {
|
try {
|
||||||
area = _search_rsdp(_map_io(BIOS_BASE, BIOS_SIZE, cap));
|
area = _search_rsdp(_map_io(BIOS_BASE, BIOS_SIZE, cap));
|
||||||
return area;
|
return area;
|
||||||
} catch (...) { env()->parent()->close(cap); }
|
} catch (...) { env.parent().close(cap); }
|
||||||
|
|
||||||
/* search EBDA (BIOS addr + 0x40e) */
|
/* search EBDA (BIOS addr + 0x40e) */
|
||||||
try {
|
try {
|
||||||
area = _map_io(0x0, 0x1000, cap);
|
area = _map_io(0x0, 0x1000, cap);
|
||||||
if (area) {
|
if (area) {
|
||||||
unsigned short base = (*reinterpret_cast<unsigned short *>(area + 0x40e)) << 4;
|
unsigned short base = (*reinterpret_cast<unsigned short *>(area + 0x40e)) << 4;
|
||||||
env()->parent()->close(cap);
|
env.parent().close(cap);
|
||||||
area = _map_io(base, 1024, cap);
|
area = _map_io(base, 1024, cap);
|
||||||
area = _search_rsdp(area);
|
area = _search_rsdp(area);
|
||||||
}
|
}
|
||||||
return area;
|
return area;
|
||||||
} catch (...) { env()->parent()->close(cap); }
|
} catch (...) { env.parent().close(cap); }
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void _parse_tables(T * entries, uint32_t count)
|
void _parse_tables(Genode::Allocator &alloc, T * entries, uint32_t count)
|
||||||
{
|
{
|
||||||
/* search for SSDT and DSDT tables */
|
/* search for SSDT and DSDT tables */
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
@ -1181,23 +1177,23 @@ class Acpi_table
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
PDBG("Found %s", table.name());
|
PDBG("Found %s", table.name());
|
||||||
|
|
||||||
Element::parse(table.table());
|
Element::parse(alloc, table.table());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.is_madt()) {
|
if (table.is_madt()) {
|
||||||
PDBG("Found MADT");
|
PDBG("Found MADT");
|
||||||
|
|
||||||
table.parse_madt();
|
table.parse_madt(alloc);
|
||||||
}
|
}
|
||||||
if (table.is_mcfg()) {
|
if (table.is_mcfg()) {
|
||||||
PDBG("Found MCFG");
|
PDBG("Found MCFG");
|
||||||
|
|
||||||
table.parse_mcfg();
|
table.parse_mcfg(alloc);
|
||||||
}
|
}
|
||||||
if (table.is_dmar()) {
|
if (table.is_dmar()) {
|
||||||
PDBG("Found DMAR");
|
PDBG("Found DMAR");
|
||||||
|
|
||||||
table.parse_dmar();
|
table.parse_dmar(alloc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1207,7 +1203,7 @@ class Acpi_table
|
|||||||
if (verbose)
|
if (verbose)
|
||||||
PDBG("Found dsdt %s", table.name());
|
PDBG("Found dsdt %s", table.name());
|
||||||
|
|
||||||
Element::parse(table.table());
|
Element::parse(alloc, table.table());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1216,7 +1212,8 @@ class Acpi_table
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Acpi_table()
|
Acpi_table(Genode::Env &env, Genode::Allocator &alloc)
|
||||||
|
: env(env), alloc(alloc)
|
||||||
{
|
{
|
||||||
Io_mem_session_capability io_mem;
|
Io_mem_session_capability io_mem;
|
||||||
|
|
||||||
@ -1224,7 +1221,7 @@ class Acpi_table
|
|||||||
|
|
||||||
struct rsdp {
|
struct rsdp {
|
||||||
char signature[8];
|
char signature[8];
|
||||||
uint8_t checksum;
|
uint8_t checksum;
|
||||||
char oemid[6];
|
char oemid[6];
|
||||||
uint8_t revision;
|
uint8_t revision;
|
||||||
/* table pointer at 16 byte offset in RSDP structure (5.2.5.3) */
|
/* table pointer at 16 byte offset in RSDP structure (5.2.5.3) */
|
||||||
@ -1233,7 +1230,7 @@ class Acpi_table
|
|||||||
uint32_t len;
|
uint32_t len;
|
||||||
uint64_t xsdt;
|
uint64_t xsdt;
|
||||||
uint8_t checksum_extended;
|
uint8_t checksum_extended;
|
||||||
uint8_t reserved[3];
|
uint8_t reserved[3];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
struct rsdp * rsdp = reinterpret_cast<struct rsdp *>(ptr_rsdp);
|
struct rsdp * rsdp = reinterpret_cast<struct rsdp *>(ptr_rsdp);
|
||||||
|
|
||||||
@ -1255,22 +1252,22 @@ class Acpi_table
|
|||||||
addr_t const xsdt = rsdp->xsdt;
|
addr_t const xsdt = rsdp->xsdt;
|
||||||
uint8_t const acpi_revision = rsdp->revision;
|
uint8_t const acpi_revision = rsdp->revision;
|
||||||
/* drop rsdp io_mem mapping since rsdt/xsdt may overlap */
|
/* drop rsdp io_mem mapping since rsdt/xsdt may overlap */
|
||||||
env()->parent()->close(io_mem);
|
env.parent().close(io_mem);
|
||||||
|
|
||||||
if (acpi_revision != 0 && xsdt && sizeof(addr_t) != sizeof(uint32_t)) {
|
if (acpi_revision != 0 && xsdt && sizeof(addr_t) != sizeof(uint32_t)) {
|
||||||
/* running 64bit and xsdt is valid */
|
/* running 64bit and xsdt is valid */
|
||||||
Table_wrapper table(xsdt);
|
Table_wrapper table(xsdt);
|
||||||
uint64_t * entries = reinterpret_cast<uint64_t *>(table.table() + 1);
|
uint64_t * entries = reinterpret_cast<uint64_t *>(table.table() + 1);
|
||||||
_parse_tables(entries, table.entry_count(entries));
|
_parse_tables(alloc, entries, table.entry_count(entries));
|
||||||
} else {
|
} else {
|
||||||
/* running (32bit) or (64bit and xsdt isn't valid) */
|
/* running (32bit) or (64bit and xsdt isn't valid) */
|
||||||
Table_wrapper table(rsdt);
|
Table_wrapper table(rsdt);
|
||||||
uint32_t * entries = reinterpret_cast<uint32_t *>(table.table() + 1);
|
uint32_t * entries = reinterpret_cast<uint32_t *>(table.table() + 1);
|
||||||
_parse_tables(entries, table.entry_count(entries));
|
_parse_tables(alloc, entries, table.entry_count(entries));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free up memory of elements not of any use */
|
/* free up memory of elements not of any use */
|
||||||
Element::clean_list();
|
Element::clean_list(alloc);
|
||||||
|
|
||||||
/* free up io memory */
|
/* free up io memory */
|
||||||
acpi_memory().free_io_memory();
|
acpi_memory().free_io_memory();
|
||||||
@ -1278,15 +1275,6 @@ class Acpi_table
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse acpi table
|
|
||||||
*/
|
|
||||||
static void init_acpi_table()
|
|
||||||
{
|
|
||||||
static Acpi_table table;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void attribute_hex(Xml_generator &xml, char const *name,
|
static void attribute_hex(Xml_generator &xml, char const *name,
|
||||||
unsigned long long value)
|
unsigned long long value)
|
||||||
{
|
{
|
||||||
@ -1296,9 +1284,10 @@ static void attribute_hex(Xml_generator &xml, char const *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Acpi::generate_report()
|
void Acpi::generate_report(Genode::Env &env, Genode::Allocator &alloc)
|
||||||
{
|
{
|
||||||
init_acpi_table();
|
/* parse table */
|
||||||
|
Acpi_table acpi_table(env, alloc);
|
||||||
|
|
||||||
enum { REPORT_SIZE = 4 * 4096 };
|
enum { REPORT_SIZE = 4 * 4096 };
|
||||||
static Reporter acpi("acpi", "acpi", REPORT_SIZE);
|
static Reporter acpi("acpi", "acpi", REPORT_SIZE);
|
||||||
@ -1373,7 +1362,7 @@ void Acpi::generate_report()
|
|||||||
if (!e->is_device())
|
if (!e->is_device())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Pci_routing *r = e->pci_list()->first();
|
Pci_routing *r = e->pci_list().first();
|
||||||
for (; r; r = r->next()) {
|
for (; r; r = r->next()) {
|
||||||
xml.node("routing", [&] () {
|
xml.node("routing", [&] () {
|
||||||
attribute_hex(xml, "gsi", r->gsi());
|
attribute_hex(xml, "gsi", r->gsi());
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
* Copyright (C) 2009-2016 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
@ -14,12 +14,16 @@
|
|||||||
#ifndef _ACPI_H_
|
#ifndef _ACPI_H_
|
||||||
#define _ACPI_H_
|
#define _ACPI_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/env.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Acpi
|
namespace Acpi
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Generate report rom
|
* Generate report rom
|
||||||
*/
|
*/
|
||||||
void generate_report();
|
void generate_report(Genode::Env&, Genode::Allocator&);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _ACPI_H_ */
|
#endif /* _ACPI_H_ */
|
||||||
|
@ -5,33 +5,53 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2015 Genode Labs GmbH
|
* Copyright (C) 2009-2016 Genode Labs GmbH
|
||||||
*
|
*
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <base/printf.h>
|
/* Genode includes */
|
||||||
#include <base/sleep.h>
|
#include <base/component.h>
|
||||||
|
#include <base/heap.h>
|
||||||
|
#include <base/log.h>
|
||||||
|
#include <util/xml_generator.h>
|
||||||
|
|
||||||
#include <os/reporter.h>
|
/* local includes */
|
||||||
|
#include <acpi.h>
|
||||||
|
|
||||||
#include "acpi.h"
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
namespace Acpi {
|
||||||
{
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
try {
|
struct Main;
|
||||||
Acpi::generate_report();
|
}
|
||||||
} catch (Genode::Xml_generator::Buffer_exceeded) {
|
|
||||||
PERR("ACPI report too large - failure");
|
struct Acpi::Main
|
||||||
throw;
|
{
|
||||||
} catch (...) {
|
Genode::Env &env;
|
||||||
PERR("Unknown exception occured - failure");
|
Genode::Heap heap { env.ram(), env.rm() };
|
||||||
throw;
|
|
||||||
}
|
Main(Env &env) : env(env)
|
||||||
|
{
|
||||||
Genode::sleep_forever();
|
try {
|
||||||
return 0;
|
Acpi::generate_report(env, heap);
|
||||||
|
} catch (Genode::Xml_generator::Buffer_exceeded) {
|
||||||
|
Genode::error("ACPI report too large - failure");
|
||||||
|
throw;
|
||||||
|
} catch (...) {
|
||||||
|
Genode::error("Unknown exception occured - failure");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/***************
|
||||||
|
** Component **
|
||||||
|
***************/
|
||||||
|
|
||||||
|
namespace Component {
|
||||||
|
Genode::size_t stack_size() { return 2*1024*sizeof(long); }
|
||||||
|
void construct(Genode::Env &env) { static Acpi::Main main(env); }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user