lx_kit & lx_emul: use generic platform API

* Remove wrapper for legacy x86 platform API
* Move PCI configuration space quirks to corresponding driver
  (pc_usb_host_drv, pc_wifi_drv, pc_intel_fb_drv)
* Adapt driver test run-scripts to changed configuration

Ref genodelabs/genode#4578
This commit is contained in:
Stefan Kalkowski 2022-07-29 17:31:20 +02:00 committed by Christian Helmuth
parent 9f9a5186e0
commit 5528434fb6
53 changed files with 1308 additions and 1835 deletions

View File

@ -58,9 +58,6 @@ SPEC_ARCH := x86_32
SRC_C += lx_emul/shadow/arch/x86/kernel/irq.c
SRC_C += lx_emul/shadow/arch/x86/kernel/setup_percpu.c
# temporarily add the following include path for x86 platform_session wrapper
INC_DIR += $(DDE_LINUX_DIR)/src/include/spec/x86/lx_kit
endif
ifeq ($(filter-out $(SPECS),x86_64),)
@ -70,9 +67,6 @@ SPEC_ARCH := x86_64
SRC_C += lx_emul/shadow/arch/x86/kernel/irq.c
SRC_C += lx_emul/shadow/arch/x86/kernel/setup_percpu.c
# temporarily add the following include path for x86 platform_session wrapper
INC_DIR += $(DDE_LINUX_DIR)/src/include/spec/x86/lx_kit
endif
ifeq ($(filter-out $(SPECS),arm),)

View File

@ -14,7 +14,6 @@ SRC_C += usb/host/uhci-hcd.c
SRC_C += usb/host/xhci-pci.c
SRC_CC += lx_kit/mapped_io_mem_range.cc
SRC_CC += lx_kit/pci.cc
SRC_CC += spec/x86/platform.cc

View File

@ -0,0 +1,56 @@
/*
* \brief Lx_emul support for accessing PCI devices
* \author Stefan Kalkowski
* \date 2022-05-23
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _LX_EMUL__PCI_H_
#define _LX_EMUL__PCI_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*lx_emul_add_resource_callback_t)
(void * dev,
unsigned number,
unsigned long addr,
unsigned long size,
int io_port);
typedef void (*lx_emul_add_device_callback_t)
(void * bus,
unsigned number,
char const * const name,
unsigned short vendor_id,
unsigned short device_id,
unsigned short sub_vendor,
unsigned short sub_device,
unsigned int class_code,
unsigned char revision,
unsigned irq);
void lx_emul_pci_for_each_resource(const char * const name, void * dev,
lx_emul_add_resource_callback_t fn);
void lx_emul_pci_for_each_device(void * bus, lx_emul_add_device_callback_t fn);
void lx_emul_pci_enable(const char * const name);
void * lx_emul_pci_root_bus(void);
#ifdef __cplusplus
}
#endif
#endif /* _LX_EMUL__PCI_H_ */

View File

@ -1,28 +0,0 @@
/*
* \brief Lx_emul support for accessing PCI(e) config space
* \author Josef Soentgen
* \date 2022-01-18
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _LX_EMUL__PCI_CONFIG_SPACE_H_
#define _LX_EMUL__PCI_CONFIG_SPACE_H_
#ifdef __cplusplus
extern "C" {
#endif
int lx_emul_pci_read_config(unsigned bus, unsigned devfn, unsigned reg, unsigned len, unsigned *val);
int lx_emul_pci_write_config(unsigned bus, unsigned devfn, unsigned reg, unsigned len, unsigned val);
#ifdef __cplusplus
}
#endif
#endif /* _LX_EMUL__PCI_CONFIG_SPACE_H_ */

View File

@ -19,6 +19,7 @@
#include <irq_session/client.h>
#include <io_mem_session/client.h>
#include <platform_session/device.h>
#include <pci/types.h>
#include <util/list.h>
#include <util/xml_node.h>
@ -35,10 +36,7 @@ struct clk {
class Lx_kit::Device : List<Device>::Element
{
private:
friend class Device_list;
friend class List<Device>;
public:
using Name = String<64>;
using Type = Platform::Device::Type;
@ -47,16 +45,17 @@ class Lx_kit::Device : List<Device>::Element
{
using Index = Platform::Device::Mmio::Index;
Index idx;
addr_t addr;
size_t size;
Index idx;
addr_t addr;
size_t size;
unsigned pci_bar;
Constructible<Platform::Device::Mmio> io_mem {};
bool match(addr_t addr, size_t size);
Io_mem(unsigned idx, addr_t addr, size_t size)
: idx{idx}, addr(addr), size(size) {}
Io_mem(unsigned idx, addr_t addr, size_t size, unsigned pci_bar)
: idx{idx}, addr(addr), size(size), pci_bar(pci_bar) {}
};
struct Irq : List<Irq>::Element
@ -81,13 +80,15 @@ class Lx_kit::Device : List<Device>::Element
Index idx;
uint16_t addr;
uint16_t size;
unsigned pci_bar;
Constructible<Platform::Device::Io_port_range> io_port {};
bool match(uint16_t addr);
Io_port(unsigned idx, uint16_t addr, uint16_t size)
: idx{idx}, addr(addr), size(size) {}
Io_port(unsigned idx, uint16_t addr, uint16_t size,
unsigned pci_bar)
: idx{idx}, addr(addr), size(size), pci_bar(pci_bar) {}
};
struct Clock : List<Clock>::Element
@ -100,6 +101,21 @@ class Lx_kit::Device : List<Device>::Element
: idx(idx), name(name), lx_clock{0} {}
};
struct Pci_config
{
Pci::vendor_t vendor_id;
Pci::device_t device_id;
Pci::class_t class_code;
Pci::rev_t rev;
Pci::vendor_t sub_v_id;
Pci::device_t sub_d_id;
};
private:
friend class Device_list;
friend class List<Device>;
Device(Entrypoint & ep,
Platform::Connection & plat,
Xml_node & xml,
@ -108,23 +124,12 @@ class Lx_kit::Device : List<Device>::Element
Platform::Connection & _platform;
Name const _name;
Type const _type;
List<Io_mem> _io_mems {};
List<Io_port> _io_ports {};
List<Irq> _irqs {};
List<Clock> _clocks {};
Constructible<Platform::Device> _pdev {};
template <typename FN>
void _for_each_io_mem(FN const & fn) {
for (Io_mem * i = _io_mems.first(); i; i = i->next()) fn(*i); }
template <typename FN>
void _for_each_io_port(FN const & fn) {
for (Io_port * i = _io_ports.first(); i; i = i->next()) fn(*i); }
template <typename FN>
void _for_each_irq(FN const & fn) {
for (Irq * i = _irqs.first(); i; i = i->next()) fn(*i); }
List<Io_mem> _io_mems {};
List<Io_port> _io_ports {};
List<Irq> _irqs {};
List<Clock> _clocks {};
Constructible<Pci_config> _pci_config {};
Constructible<Platform::Device> _pdev {};
template <typename FN>
void _for_each_clock(FN const & fn) {
@ -133,7 +138,23 @@ class Lx_kit::Device : List<Device>::Element
public:
const char * compatible();
const char * name();
Name name();
template <typename FN>
void for_each_io_mem(FN const & fn) {
for (Io_mem * i = _io_mems.first(); i; i = i->next()) fn(*i); }
template <typename FN>
void for_each_io_port(FN const & fn) {
for (Io_port * i = _io_ports.first(); i; i = i->next()) fn(*i); }
template <typename FN>
void for_each_irq(FN const & fn) {
for (Irq * i = _irqs.first(); i; i = i->next()) fn(*i); }
template <typename FN>
void for_pci_config(FN const & fn) {
if (_pci_config.constructed()) fn(*_pci_config); }
void enable();
clk * clock(const char * name);
@ -163,12 +184,21 @@ class Lx_kit::Device_list : List<Device>
Platform::Connection & _platform;
void _handle_signal() {}
public:
template <typename FN>
void for_each(FN const & fn) {
for (Device * d = first(); d; d = d->next()) fn(*d); }
template <typename FN>
void with_xml(FN const & fn)
{
_platform.update();
_platform.with_xml([&] (Xml_node & xml) { fn(xml); });
}
Device_list(Entrypoint & ep,
Heap & heap,
Platform::Connection & platform);

View File

@ -1,87 +0,0 @@
/*
* \brief Dummy - platform session device interface
* \author Stefan Kalkowski
* \date 2022-01-07
*/
/*
* Copyright (C) 2021 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 _PLATFORM_SESSION__CONNECTION_H_
#define _PLATFORM_SESSION__CONNECTION_H_
#include <util/mmio.h>
#include <util/string.h>
#include <base/exception.h>
#include <io_mem_session/client.h>
#include <irq_session/client.h>
namespace Platform {
struct Connection;
class Dma_buffer;
using namespace Genode;
}
#define Platform Legacy_platform
#include <legacy/x86/platform_session/connection.h>
#undef Platform
struct Platform::Connection
{
Env &_env;
Region_map &_rm { _env.rm() };
char _devices_node_buffer[4096u] { };
Constructible<Xml_node> _devices_node { };
Constructible<Legacy_platform::Connection> _legacy_platform { };
struct Device
{
using Name = String<16>;
Name name { };
Legacy_platform::Device_capability cap { };
Device(Name const &name, Legacy_platform::Device_capability cap)
: name { name }, cap { cap } { }
};
enum : unsigned char { MAX_DEVICES = 4 };
Constructible<Device> _devices_list[MAX_DEVICES] { };
Legacy_platform::Device_capability device_cap(char const *name);
Connection(Env &);
/********************************
** Platform session interface **
********************************/
void update();
template <typename FN> void with_xml(FN const & fn)
{
if (_devices_node.constructed())
fn(*_devices_node);
}
Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache);
void free_dma_buffer(Ram_dataspace_capability);
addr_t dma_addr(Ram_dataspace_capability);
template <typename FUNC>
auto retry_with_upgrade(Ram_quota ram, Cap_quota caps, FUNC func) -> decltype(func())
{
return _legacy_platform->retry_with_upgrade<FUNC>(ram, caps, func);
}
};
#endif /* _PLATFORM_SESSION__CONNECTION_H_ */

View File

@ -1,181 +0,0 @@
/*
* \brief Dummy - platform session device interface
* \author Stefan Kalkowski
* \date 2022-01-07
*/
/*
* Copyright (C) 2021 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 _PLATFORM_SESSION__DEVICE_H_
#define _PLATFORM_SESSION__DEVICE_H_
/* Genode includes */
#include <base/attached_dataspace.h>
#include <base/exception.h>
#include <io_mem_session/client.h>
#include <io_port_session/client.h>
#include <irq_session/client.h>
#include <platform_session/connection.h>
#include <util/mmio.h>
#include <util/string.h>
namespace Platform {
struct Connection;
class Device;
using namespace Genode;
}
class Platform::Device : Interface, Noncopyable
{
public:
struct Range { addr_t start; size_t size; };
struct Mmio;
struct Io_port_range;
struct Irq;
struct Config_space;
using Name = String<64>;
private:
Connection &_platform;
Legacy_platform::Device_capability _device_cap { };
Name _name { };
unsigned _class_code { };
public:
int _bar_checked_for_size[6] { };
struct Index { unsigned value; };
explicit Device(Connection &platform)
: _platform { platform } { }
struct Type { String<64> name; };
Device(Connection &platform, Type type);
Device(Connection &platform, Name name);
~Device() { }
Name const &name() const
{
return _name;
}
};
class Platform::Device::Mmio : Range
{
public:
struct Index { unsigned value; };
private:
Constructible<Attached_dataspace> _attached_ds { };
void *_local_addr();
Device &_device;
Index _index;
public:
Mmio(Device &device, Index index)
: _device { device }, _index { index } { }
explicit Mmio(Device &device)
: _device { device }, _index { ~0u } { }
size_t size() const;
template <typename T>
T *local_addr() { return reinterpret_cast<T *>(_local_addr()); }
};
class Platform::Device::Io_port_range : Noncopyable
{
public:
struct Index { unsigned value; };
private:
Device &_device;
Index _index;
Constructible<Io_port_session_client> _io_port { };
public:
Io_port_range(Device &device, Index index);
explicit Io_port_range(Device &device)
: _device { device }, _index { ~0u } { }
uint8_t inb(uint16_t addr);
uint16_t inw(uint16_t addr);
uint32_t inl(uint16_t addr);
void outb(uint16_t addr, uint8_t val);
void outw(uint16_t addr, uint16_t val);
void outl(uint16_t addr, uint32_t val);
};
class Platform::Device::Irq : Noncopyable
{
public:
struct Index { unsigned value; };
private:
Device &_device;
Index _index;
Constructible<Irq_session_client> _irq { };
public:
Irq(Device &device, Index index);
explicit Irq(Device &device)
: _device { device }, _index { ~0u } { }
void ack();
void sigh(Signal_context_capability);
void sigh_omit_initial_signal(Signal_context_capability);
};
class Platform::Device::Config_space : Noncopyable
{
public:
Device &_device;
enum class Access_size : unsigned { ACCESS_8BIT, ACCESS_16BIT, ACCESS_32BIT };
Config_space(Device &device) : _device { device } { }
unsigned read(unsigned char address, Access_size size);
void write(unsigned char address, unsigned value, Access_size size);
};
#endif /* _PLATFORM_SESSION__DEVICE_H_ */

View File

@ -0,0 +1,104 @@
/*
* \brief Lx_emul backend for PCI devices
* \author Stefan Kalkowski
* \date 2022-05-23
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <base/log.h>
#include <pci/types.h>
#include <lx_emul/init.h>
#include <lx_emul/pci.h>
#include <lx_kit/env.h>
extern "C" void lx_emul_pci_enable(const char * const name)
{
using namespace Lx_kit;
env().devices.for_each([&] (Device & d) {
if (d.name() == name) d.enable(); });
};
extern "C" void
lx_emul_pci_for_each_resource(const char * const name, void * dev,
lx_emul_add_resource_callback_t fn)
{
using namespace Lx_kit;
using namespace Genode;
using namespace Pci;
env().devices.for_each([&] (Device & d) {
if (d.name() != name)
return;
d.for_each_io_mem([&] (Device::Io_mem & io_mem) {
fn(dev, io_mem.pci_bar, io_mem.addr, io_mem.size, 0);
});
d.for_each_io_port([&] (Device::Io_port & io_port) {
fn(dev, io_port.pci_bar, io_port.addr, io_port.size, 1);
});
});
}
extern "C" void
lx_emul_pci_for_each_device(void * bus, lx_emul_add_device_callback_t fn)
{
using namespace Lx_kit;
using namespace Genode;
using namespace Pci;
unsigned num = 0;
env().devices.for_each([&] (Device & d) {
unsigned irq = 0;
d.for_each_irq([&] (Device::Irq & i) {
if (!irq) irq = i.number; });
d.for_pci_config([&] (Device::Pci_config & cfg) {
fn(bus, num++, d.name().string(), cfg.vendor_id, cfg.device_id,
cfg.sub_v_id, cfg.sub_d_id, cfg.class_code, cfg.rev, irq);
});
});
}
static const char * lx_emul_pci_final_fixups[] = {
"__pci_fixup_final_quirk_usb_early_handoff",
"END_OF_PCI_FIXUPS"
};
extern "C" __attribute__((weak)) int inhibit_pci_fixup(char const *)
{
return 0;
}
extern "C" void lx_emul_register_pci_fixup(void (*fn)(struct pci_dev*), const char * name)
{
if (inhibit_pci_fixup(name))
return;
for (unsigned i = 0; i < (sizeof(lx_emul_pci_final_fixups) / sizeof(char*));
i++) {
if (Genode::strcmp(name, lx_emul_pci_final_fixups[i]) == 0) {
Lx_kit::env().pci_fixup_calls.add(fn);
return;
}
}
Genode::error(__func__, " ignore unkown PCI fixup '", name, "'");
}
extern "C" void lx_emul_execute_pci_fixup(struct pci_dev *pci_dev)
{
Lx_kit::env().pci_fixup_calls.execute(pci_dev);
}

View File

@ -0,0 +1,199 @@
/*
* \brief PCI backend
* \author Josef Soentgen
* \date 2022-05-10
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <lx_emul.h>
#include <lx_emul/io_mem.h>
#include <lx_emul/pci.h>
#include <linux/irq.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
extern void lx_backtrace(void);
int arch_probe_nr_irqs(void)
{
/* needed for 'irq_get_irq_data()' in 'pci_assign_irq()' below */
return 256;
}
static const struct attribute_group *pci_dev_attr_groups[] = {
NULL,
};
const struct device_type pci_dev_type = {
.groups = pci_dev_attr_groups,
};
extern const struct device_type pci_dev_type;
static struct pci_bus *_pci_bus;
void * lx_emul_pci_root_bus()
{
return _pci_bus;
}
static struct device * host_bridge_device = NULL;
extern struct device * pci_get_host_bridge_device(struct pci_dev * dev);
struct device * pci_get_host_bridge_device(struct pci_dev * dev)
{
return host_bridge_device;
}
static struct pci_dev *_pci_alloc_dev(struct pci_bus *bus)
{
struct pci_dev *dev;
dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
if (!dev)
return NULL;
INIT_LIST_HEAD(&dev->bus_list);
dev->dev.type = &pci_dev_type;
dev->bus = bus;
return dev;
}
static void pci_add_resource_to_device_callback(void * data,
unsigned number,
unsigned long addr,
unsigned long size,
int io_port)
{
struct pci_dev * dev = (struct pci_dev*) data;
dev->resource[number].start = addr;
dev->resource[number].end = dev->resource[number].start + size - 1;
if (io_port)
dev->resource[number].flags |= IORESOURCE_IO;
}
static void pci_add_single_device_callback(void * data,
unsigned number,
char const * const name,
u16 vendor_id,
u16 device_id,
u16 sub_vendor,
u16 sub_device,
u32 class_code,
u8 revision,
unsigned irq)
{
struct pci_bus * bus = (struct pci_bus*) data;
struct pci_dev * dev = _pci_alloc_dev(bus);
if (!dev) {
printk("Error: out of memory, cannot allocate pci device %s\n", name);
return;
}
dev->devfn = number * 8;
dev->vendor = vendor_id;
dev->device = device_id;
dev->subsystem_vendor = sub_vendor;
dev->subsystem_device = sub_device;
dev->irq = irq;
dev->dma_mask = 0xffffffff;
dev->dev.bus = &pci_bus_type;
dev->revision = revision;
dev->class = class_code;
dev->current_state = PCI_UNKNOWN;
lx_emul_pci_for_each_resource(name, dev,
pci_add_resource_to_device_callback);
list_add_tail(&dev->bus_list, &bus->devices);
device_initialize(&dev->dev);
dev_set_name(&dev->dev, name);
dev->dev.dma_mask = &dev->dma_mask;
if (number == 0) { /* host bridge */
host_bridge_device = &dev->dev;
bus->bridge = &dev->dev;
}
dev->match_driver = false;
if (device_add(&dev->dev)) {
list_del(&dev->bus_list);
kfree(dev);
printk("Error: could not add pci device %s\n", name);
return;
}
lx_emul_execute_pci_fixup(dev);
dev->match_driver = true;
if (device_attach(&dev->dev)) {
list_del(&dev->bus_list);
kfree(dev);
printk("Error: could not attach pci device %s\n", name);
return;
}
}
static int __init pci_subsys_init(void)
{
struct pci_bus *b;
struct pci_sysdata *sd;
/* pci_alloc_bus(NULL) */
b = kzalloc(sizeof (struct pci_bus), GFP_KERNEL);
if (!b)
return -ENOMEM;
sd = kzalloc(sizeof (struct pci_sysdata), GFP_KERNEL);
if (!sd) {
kfree(b);
return -ENOMEM;
}
/* needed by intel_fb */
sd->domain = 0;
b->sysdata = sd;
INIT_LIST_HEAD(&b->node);
INIT_LIST_HEAD(&b->children);
INIT_LIST_HEAD(&b->devices);
INIT_LIST_HEAD(&b->slots);
INIT_LIST_HEAD(&b->resources);
b->max_bus_speed = PCI_SPEED_UNKNOWN;
b->cur_bus_speed = PCI_SPEED_UNKNOWN;
_pci_bus = b;
/* add host bridge device */
pci_add_single_device_callback(b, 0, "00:00.0", 0x8086, 0x44, 0x17aa, 0x2193, 0x60000, 2, 0);
/* attach PCI devices */
lx_emul_pci_for_each_device(b, pci_add_single_device_callback);
return 0;
}
subsys_initcall(pci_subsys_init);

View File

@ -1,82 +0,0 @@
/*
* \brief Lx_emul backend for accessing PCI(e) config space
* \author Josef Soentgen
* \date 2022-01-18
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <lx_kit/env.h>
#include <lx_emul/pci_config_space.h>
using Device_name = Genode::String<16>;
template <typename T, typename... TAIL>
static Device_name to_string(T const &arg, TAIL &&... args)
{
return Device_name(arg, args...);
}
static Device_name assemble(unsigned bus, unsigned devfn)
{
using namespace Genode;
return to_string("pci-",
Hex(bus, Hex::OMIT_PREFIX), ":",
Hex((devfn >> 3) & 0x1fu, Hex::OMIT_PREFIX), ".",
Hex(devfn & 0x7u, Hex::OMIT_PREFIX));
}
int lx_emul_pci_read_config(unsigned bus, unsigned devfn,
unsigned reg, unsigned len, unsigned *val)
{
using namespace Lx_kit;
using namespace Genode;
Device_name name = assemble(bus, devfn);
bool result = false;
bool matched = false;
env().devices.for_each([&] (Device & d) {
matched = name == d.name();
if (matched && val)
result = d.read_config(reg, len, val);
});
if (!result && matched)
error("could not read config space register ", Hex(reg));
return result ? 0 : -1;
}
int lx_emul_pci_write_config(unsigned bus, unsigned devfn,
unsigned reg, unsigned len, unsigned val)
{
using namespace Lx_kit;
using namespace Genode;
Device_name name = assemble(bus, devfn);
bool result = false;
bool matched = false;
env().devices.for_each ([&] (Device & d) {
matched = name == d.name();
if (matched)
result = d.write_config(reg, len, val);
});
if (!result && matched)
error("could not write config space register ", Hex(reg),
" with ", Hex(val));
return result ? 0 : -1;
}

View File

@ -1,46 +0,0 @@
/*
* \brief Lx_emul backend for PCI fixup calls
* \author Josef Soentgen
* \date 2022-02-04
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <base/log.h>
#include <lx_kit/env.h>
#include <lx_emul/init.h>
#include <lx_emul/pci_fixups.h>
extern "C" __attribute__((weak)) int inhibit_pci_fixup(char const *)
{
return 0;
}
extern "C" void lx_emul_register_pci_fixup(void (*fn)(struct pci_dev*), const char * name)
{
if (inhibit_pci_fixup(name))
return;
for (unsigned i = 0; i < (sizeof(lx_emul_pci_final_fixups) / sizeof(char*));
i++) {
if (Genode::strcmp(name, lx_emul_pci_final_fixups[i]) == 0) {
Lx_kit::env().pci_fixup_calls.add(fn);
return;
}
}
Genode::error(__func__, " ignore unkown PCI fixup '", name, "'");
}
extern "C" void lx_emul_execute_pci_fixup(struct pci_dev *pci_dev)
{
Lx_kit::env().pci_fixup_calls.execute(pci_dev);
}

View File

@ -0,0 +1,11 @@
#include <linux/pci.h>
void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
struct resource *res)
{
region->start = res->start;
region->end = res->end;
}
void pci_put_host_bridge_device(struct device * dev) { }

View File

@ -0,0 +1,34 @@
#include <linux/pci.h>
static struct attribute *pci_bus_attrs[] = {
NULL,
};
static const struct attribute_group pci_bus_group = {
.attrs = pci_bus_attrs,
};
const struct attribute_group *pci_bus_groups[] = {
&pci_bus_group,
NULL,
};
static struct attribute *pci_dev_attrs[] = {
NULL,
};
static const struct attribute_group pci_dev_group = {
.attrs = pci_dev_attrs,
};
const struct attribute_group *pci_dev_groups[] = {
&pci_dev_group,
NULL,
};

View File

@ -0,0 +1,36 @@
#include <linux/pci.h>
#include <lx_emul/pci.h>
int pci_enable_device(struct pci_dev * dev)
{
lx_emul_pci_enable(dev_name(&dev->dev));
return 0;
}
int pcim_enable_device(struct pci_dev *pdev)
{
/* for now ignore devres */
return pci_enable_device(pdev);
}
void pci_set_master(struct pci_dev * dev) { }
int pci_set_mwi(struct pci_dev * dev)
{
return 1;
}
bool pci_dev_run_wake(struct pci_dev * dev)
{
return false;
}
u8 pci_find_capability(struct pci_dev * dev,int cap)
{
return 0;
}

View File

@ -0,0 +1,44 @@
#include <lx_emul/pci.h>
#include <linux/pci.h>
struct pci_dev * pci_get_class(unsigned int class, struct pci_dev *from)
{
struct pci_dev *dev;
struct pci_bus *bus = (struct pci_bus *) lx_emul_pci_root_bus();
/*
* Break endless loop (see 'intel_dsm_detect()') by only querying
* the bus on the first executuin.
*/
if (from)
return NULL;
list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->class == class) {
return dev;
}
}
return NULL;
}
struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus,
unsigned int devfn)
{
struct pci_dev *dev;
struct pci_bus *pbus = (struct pci_bus *) lx_emul_pci_root_bus();
list_for_each_entry(dev, &pbus->devices, bus_list) {
if (dev->devfn == devfn && dev->class == 0x60000)
return dev;
}
return NULL;
}
struct pci_dev * pci_get_device(unsigned int vendor,unsigned int device,struct pci_dev * from)
{
return NULL;
}

View File

@ -0,0 +1,24 @@
#include <linux/pci.h>
#include <linux/irq.h>
extern struct irq_chip dde_irqchip_data_chip;
void pci_assign_irq(struct pci_dev * dev)
{
struct irq_data *irq_data;
/*
* Be lazy and treat irq as hwirq as this is used by the
* dde_irqchip_data_chip for (un-)masking.
*/
irq_data = irq_get_irq_data(dev->irq);
irq_data->hwirq = dev->irq;
irq_set_chip_and_handler(dev->irq, &dde_irqchip_data_chip,
handle_level_irq);
}

View File

@ -0,0 +1,11 @@
#include <linux/pci.h>
resource_size_t __weak pcibios_align_resource(void *data,
const struct resource *res,
resource_size_t size,
resource_size_t align)
{
return res->start;
}

View File

@ -1,194 +0,0 @@
/*
* \brief Linux kernel PCI
* \author Josef Soentgen
* \date 2022-01-14
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <lx_emul.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
int arch_probe_nr_irqs(void)
{
return 16;
}
#include <asm/x86_init.h>
static int x86_init_pci_init(void)
{
return 1;
}
static void x86_init_pci_init_irq(void) { }
struct x86_init_ops x86_init = {
.pci = {
.init = x86_init_pci_init,
.init_irq = x86_init_pci_init_irq,
},
};
#include <lx_emul/pci_config_space.h>
#include <linux/pci.h>
#include <asm/pci.h>
#include <asm/pci_x86.h>
static int pci_raw_ops_read(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 *val)
{
return lx_emul_pci_read_config(bus, devfn, (unsigned)reg, (unsigned)len, val);
}
static int pci_raw_ops_write(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 val)
{
return lx_emul_pci_write_config(bus, devfn, (unsigned)reg, (unsigned)len, val);
}
const struct pci_raw_ops genode_raw_pci_ops = {
.read = pci_raw_ops_read,
.write = pci_raw_ops_write,
};
const struct pci_raw_ops *raw_pci_ops = &genode_raw_pci_ops;
static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
return pci_raw_ops_read(0, bus->number, devfn, where, size, value);
}
static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
return pci_raw_ops_write(0, bus->number, devfn, where, size, value);
}
struct pci_ops pci_root_ops = {
.read = pci_read,
.write = pci_write,
};
#include <lx_emul/init.h>
static struct resource _dummy_parent;
void pcibios_scan_root(int busnum)
{
struct pci_bus *bus;
struct pci_sysdata *sd;
struct pci_dev *dev;
LIST_HEAD(resources);
sd = kzalloc(sizeof(*sd), GFP_KERNEL);
if (!sd) {
return;
}
sd->node = NUMA_NO_NODE;
pci_add_resource(&resources, &ioport_resource);
pci_add_resource(&resources, &iomem_resource);
bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources);
if (!bus) {
pci_free_resource_list(&resources);
kfree(sd);
return;
}
pci_bus_add_devices(bus);
/* handle early quirks */
list_for_each_entry(dev, &bus->devices, bus_list) {
/*
* As pci_enable_resources() is only going to check if
* the parent of the resource is set register the dummy.
*/
struct resource *r;
int i;
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
r = &dev->resource[i];
r->parent = &_dummy_parent;
}
lx_emul_execute_pci_fixup(dev);
}
}
#include <linux/irq.h>
#include <linux/pci.h>
extern struct irq_chip dde_irqchip_data_chip;
void pci_assign_irq(struct pci_dev * dev)
{
struct irq_data *irq_data;
/*
* Be lazy and treat irq as hwirq as this is used by the
* dde_irqchip_data_chip for (un-)masking.
*/
irq_data = irq_get_irq_data(dev->irq);
irq_data->hwirq = dev->irq;
irq_set_chip_and_handler(dev->irq, &dde_irqchip_data_chip,
handle_level_irq);
}
#include <linux/pci.h>
unsigned long pci_mem_start = 0xaeedbabe;
const struct attribute_group aspm_ctrl_attr_group[] = { 0 };
const struct attribute_group pci_dev_vpd_attr_group = { };
struct pci_fixup __start_pci_fixups_early[] = { 0 };
struct pci_fixup __end_pci_fixups_early[] = { 0 };
struct pci_fixup __start_pci_fixups_header[] = { 0 };
struct pci_fixup __end_pci_fixups_header[] = { 0 };
struct pci_fixup __start_pci_fixups_final[] = { 0 };
struct pci_fixup __end_pci_fixups_final[] = { 0 };
struct pci_fixup __start_pci_fixups_enable[] = { 0 };
struct pci_fixup __end_pci_fixups_enable[] = { 0 };
struct pci_fixup __start_pci_fixups_resume[] = { 0 };
struct pci_fixup __end_pci_fixups_resume[] = { 0 };
struct pci_fixup __start_pci_fixups_resume_early[] = { 0 };
struct pci_fixup __end_pci_fixups_resume_early[] = { 0 };
struct pci_fixup __start_pci_fixups_suspend[] = { 0 };
struct pci_fixup __end_pci_fixups_suspend[] = { 0 };
struct pci_fixup __start_pci_fixups_suspend_late[] = { 0 };
struct pci_fixup __end_pci_fixups_suspend_late[] = { 0 };
int pcibios_last_bus = -1;
extern int __init pcibios_init(void);
int __init pcibios_init(void)
{
lx_emul_trace(__func__);
return 0;
}

View File

@ -34,7 +34,7 @@ bool Device::Io_mem::match(addr_t addr, size_t size)
bool Device::Io_port::match(uint16_t addr)
{
return (this->addr <= addr) &&
((this->addr + this->size) >= addr);
((this->addr + this->size) > addr);
}
@ -67,9 +67,9 @@ const char * Device::compatible()
}
const char * Device::name()
Device::Name Device::name()
{
return _name.string();
return _name;
}
@ -102,7 +102,7 @@ clk * Device::clock(unsigned idx)
bool Device::io_mem(addr_t phys_addr, size_t size)
{
bool ret = false;
_for_each_io_mem([&] (Io_mem & io) {
for_each_io_mem([&] (Io_mem & io) {
if (io.match(phys_addr, size))
ret = true;
});
@ -113,7 +113,7 @@ bool Device::io_mem(addr_t phys_addr, size_t size)
void * Device::io_mem_local_addr(addr_t phys_addr, size_t size)
{
void * ret = nullptr;
_for_each_io_mem([&] (Io_mem & io) {
for_each_io_mem([&] (Io_mem & io) {
if (!io.match(phys_addr, size))
return;
@ -132,7 +132,7 @@ bool Device::irq_unmask(unsigned number)
{
bool ret = false;
_for_each_irq([&] (Irq & irq) {
for_each_irq([&] (Irq & irq) {
if (irq.number != number)
return;
@ -156,7 +156,7 @@ void Device::irq_mask(unsigned number)
if (!_pdev.constructed())
return;
_for_each_irq([&] (Irq & irq) {
for_each_irq([&] (Irq & irq) {
if (irq.number != number)
return;
irq.session.destruct();
@ -170,7 +170,7 @@ void Device::irq_ack(unsigned number)
if (!_pdev.constructed())
return;
_for_each_irq([&] (Irq & irq) {
for_each_irq([&] (Irq & irq) {
if (irq.number != number || !irq.session.constructed())
return;
irq.session->ack();
@ -181,7 +181,7 @@ void Device::irq_ack(unsigned number)
bool Device::io_port(uint16_t addr)
{
bool ret = false;
_for_each_io_port([&] (Io_port & io) {
for_each_io_port([&] (Io_port & io) {
if (io.match(addr))
ret = true;
});
@ -192,7 +192,7 @@ bool Device::io_port(uint16_t addr)
uint8_t Device::io_port_inb(uint16_t addr)
{
uint8_t ret = 0;
_for_each_io_port([&] (Device::Io_port & io) {
for_each_io_port([&] (Device::Io_port & io) {
if (!io.match(addr))
return;
@ -209,7 +209,7 @@ uint8_t Device::io_port_inb(uint16_t addr)
uint16_t Device::io_port_inw(uint16_t addr)
{
uint16_t ret = 0;
_for_each_io_port([&] (Device::Io_port & io) {
for_each_io_port([&] (Device::Io_port & io) {
if (!io.match(addr))
return;
@ -226,7 +226,7 @@ uint16_t Device::io_port_inw(uint16_t addr)
uint32_t Device::io_port_inl(uint16_t addr)
{
uint32_t ret = 0;
_for_each_io_port([&] (Device::Io_port & io) {
for_each_io_port([&] (Device::Io_port & io) {
if (!io.match(addr))
return;
@ -242,7 +242,7 @@ uint32_t Device::io_port_inl(uint16_t addr)
void Device::io_port_outb(uint16_t addr, uint8_t val)
{
_for_each_io_port([&] (Device::Io_port & io) {
for_each_io_port([&] (Device::Io_port & io) {
if (!io.match(addr))
return;
@ -256,7 +256,7 @@ void Device::io_port_outb(uint16_t addr, uint8_t val)
void Device::io_port_outw(uint16_t addr, uint16_t val)
{
_for_each_io_port([&] (Device::Io_port & io) {
for_each_io_port([&] (Device::Io_port & io) {
if (!io.match(addr))
return;
@ -270,7 +270,7 @@ void Device::io_port_outw(uint16_t addr, uint16_t val)
void Device::io_port_outl(uint16_t addr, uint32_t val)
{
_for_each_io_port([&] (Device::Io_port & io) {
for_each_io_port([&] (Device::Io_port & io) {
if (!io.match(addr))
return;
@ -317,16 +317,18 @@ Device::Device(Entrypoint & ep,
{
unsigned i = 0;
xml.for_each_sub_node("io_mem", [&] (Xml_node node) {
addr_t addr = node.attribute_value("phys_addr", 0UL);
size_t size = node.attribute_value("size", 0UL);
_io_mems.insert(new (heap) Io_mem(i++, addr, size));
addr_t addr = node.attribute_value("phys_addr", 0UL);
size_t size = node.attribute_value("size", 0UL);
unsigned bar = node.attribute_value("pci_bar", 0U);
_io_mems.insert(new (heap) Io_mem(i++, addr, size, bar));
});
i = 0;
xml.for_each_sub_node("io_port", [&] (Xml_node node) {
xml.for_each_sub_node("io_port_range", [&] (Xml_node node) {
uint16_t addr = node.attribute_value<uint16_t>("phys_addr", 0U);
uint16_t size = node.attribute_value<uint16_t>("size", 0U);
_io_ports.insert(new (heap) Io_port(i++, addr, size));
unsigned bar = node.attribute_value("pci_bar", 0U);
_io_ports.insert(new (heap) Io_port(i++, addr, size, bar));
});
i = 0;
@ -339,6 +341,17 @@ Device::Device(Entrypoint & ep,
Device::Name name = node.attribute_value("name", Device::Name());
_clocks.insert(new (heap) Device::Clock(i++, name));
});
xml.for_each_sub_node("pci-config", [&] (Xml_node node) {
using namespace Pci;
_pci_config.construct(Pci_config{
node.attribute_value<vendor_t>("vendor_id", 0xffff),
node.attribute_value<device_t>("device_id", 0xffff),
node.attribute_value<class_t>("class", 0xff),
node.attribute_value<rev_t>("revision", 0xff),
node.attribute_value<vendor_t>("sub_vendor_id", 0xffff),
node.attribute_value<device_t>("sub_device_id", 0xffff)});
});
}
@ -352,9 +365,26 @@ Device_list::Device_list(Entrypoint & ep,
:
_platform(platform)
{
_platform.with_xml([&] (Xml_node & xml) {
xml.for_each_sub_node("device", [&] (Xml_node node) {
insert(new (heap) Device(ep, _platform, node, heap));
bool initialized = false;
Constructible<Io_signal_handler<Device_list>> handler {};
while (!initialized) {
_platform.update();
_platform.with_xml([&] (Xml_node & xml) {
if (!xml.num_sub_nodes()) {
if (!handler.constructed()) {
handler.construct(ep, *this, &Device_list::_handle_signal);
_platform.sigh(*handler);
}
ep.wait_and_dispatch_one_io_signal();
} else {
_platform.sigh(Signal_context_capability());
handler.destruct();
xml.for_each_sub_node("device", [&] (Xml_node node) {
insert(new (heap) Device(ep, _platform, node, heap));
});
initialized = true;
}
});
});
}
}

View File

@ -1,581 +0,0 @@
/*
* \brief Legacy platform session wrapper
* \author Josef Soentgen
* \date 2022-01-14
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
/* Genode includes */
#include <base/ram_allocator.h>
#include <util/xml_generator.h>
/* DDE includes */
#include <lx_kit/env.h>
#include <lx_kit/device.h>
#include <platform_session/device.h>
using namespace Genode;
using Str = String<16>;
template <typename T, typename... TAIL>
static Str to_string(T const &arg, TAIL &&... args)
{
return Str(arg, args...);
}
template <typename FN>
static void scan_resources(Legacy_platform::Device &device,
FN const &fn)
{
using R = Legacy_platform::Device::Resource;
for (unsigned resource_id = 0; resource_id < 6; resource_id++) {
R const resource = device.resource(resource_id);
if (resource.type() != R::INVALID)
fn(resource_id, resource);
}
}
static Str create_device_node(Xml_generator &xml,
Legacy_platform::Device &device)
{
using namespace Genode;
/* start arbitrarily and count up */
static unsigned char irq = 8;
/* start arbitrarily at the dev 1 for the first device */
static unsigned char bdf[3] = { 0, 1, 0 };
/* start arbitrarily at 1 GiB */
static unsigned long mmio_phys_addr = 0x40000000;
unsigned char pbdf[3];
device.bus_address(&pbdf[0], &pbdf[1], &pbdf[2]);
/*
* The host-bridge is only required by the Intel framebuffer
* driver and has to be located at 00:00.0. For every other
* type of device we simply count upwards.
*/
unsigned char vbdf[3] = { 0, 0, 0 };
unsigned const class_code = device.class_code() >> 8;
if (class_code != 0x600 /* host-bridge */) {
vbdf[0] = bdf[0]; vbdf[1] = bdf[1]; vbdf[2] = bdf[2];
bdf[1]++;
}
log("override physical BDF ",
Hex(pbdf[0], Hex::OMIT_PREFIX), ":",
Hex(pbdf[1], Hex::OMIT_PREFIX), ".",
Hex(pbdf[2], Hex::OMIT_PREFIX), " -> ",
Hex(vbdf[0], Hex::OMIT_PREFIX), ":",
Hex(vbdf[1], Hex::OMIT_PREFIX), ".",
Hex(vbdf[2], Hex::OMIT_PREFIX));
Str name = to_string("pci-",
Hex(vbdf[0], Hex::OMIT_PREFIX), ":",
Hex(vbdf[1], Hex::OMIT_PREFIX), ".",
Hex(vbdf[2], Hex::OMIT_PREFIX));
xml.node("device", [&] () {
xml.attribute("name", name);
xml.attribute("type", "pci");
xml.node("irq", [&] () {
xml.attribute("number", irq++);
});
using R = Legacy_platform::Device::Resource;
scan_resources(device, [&] (unsigned id, R const &r) {
bool const memory = r.type() == R::MEMORY;
if (memory) {
xml.node("io_mem", [&] () {
xml.attribute("phys_addr", to_string(Hex(mmio_phys_addr)));
xml.attribute("size", to_string(Hex(r.size())));
xml.attribute("bar", id);
});
mmio_phys_addr += align_addr(r.size(), 12);
} else {
xml.node("io_port", [&] () {
xml.attribute("phys_addr", to_string(Hex(r.bar())));
xml.attribute("size", to_string(Hex(r.size())));
xml.attribute("bar", id);
});
}
});
});
return name;
}
Platform::Connection::Connection(Env &env)
:
_env { env }
{
try {
_legacy_platform.construct(env);
} catch (...) {
error("could not construct legacy platform connection");
throw;
}
/* empirically determined */
_legacy_platform->upgrade_ram(32768);
_legacy_platform->upgrade_caps(8);
Xml_generator xml { _devices_node_buffer,
sizeof (_devices_node_buffer),
"devices", [&] () {
_legacy_platform->with_upgrade([&] () {
/* scan the virtual bus but limit to MAX_DEVICES */
Legacy_platform::Device_capability cap { };
for (auto &dev : _devices_list) {
cap = _legacy_platform->next_device(cap, 0x0u, 0x0u);
if (!cap.valid()) break;
Legacy_platform::Device_client device { cap };
Str name = create_device_node(xml, device);
dev.construct(name, cap);
}
});
} };
_devices_node.construct(_devices_node_buffer,
sizeof (_devices_node_buffer));
}
Legacy_platform::Device_capability
Platform::Connection::device_cap(char const *name)
{
for (auto const &dev : _devices_list) {
if (!dev.constructed())
continue;
if (dev->name == name)
return dev->cap;
}
return Legacy_platform::Device_capability();
}
void Platform::Connection::update() { }
Ram_dataspace_capability
Platform::Connection::alloc_dma_buffer(size_t size, Cache)
{
return _legacy_platform->with_upgrade([&] () {
return _legacy_platform->alloc_dma_buffer(size, Cache::UNCACHED);
});
}
void Platform::Connection::free_dma_buffer(Ram_dataspace_capability ds_cap)
{
_legacy_platform->free_dma_buffer(ds_cap);
}
addr_t Platform::Connection::dma_addr(Ram_dataspace_capability ds_cap)
{
return _legacy_platform->dma_addr(ds_cap);
}
static Legacy_platform::Device::Access_size convert(Platform::Device::Config_space::Access_size size)
{
using PAS = Platform::Device::Config_space::Access_size;
using LAS = Legacy_platform::Device::Access_size;
switch (size) {
case PAS::ACCESS_8BIT:
return LAS::ACCESS_8BIT;
case PAS::ACCESS_16BIT:
return LAS::ACCESS_16BIT;
case PAS::ACCESS_32BIT:
return LAS::ACCESS_32BIT;
}
return LAS::ACCESS_8BIT;
}
template <typename FN>
static void apply(Platform::Device const &device,
Xml_node const &devices,
FN const &fn)
{
using namespace Genode;
using N = Platform::Device::Name;
auto lookup_device = [&] (Xml_node const &node) {
if (node.attribute_value("name", N()) == device.name())
fn(node);
};
devices.for_each_sub_node("device", lookup_device);
}
static unsigned bar_size(Platform::Device const &dev,
Xml_node const &devices, unsigned bar)
{
if (bar > 6)
return 0;
using namespace Genode;
unsigned val = 0;
apply(dev, devices, [&] (Xml_node device) {
device.for_each_sub_node("io_mem", [&] (Xml_node node) {
if (node.attribute_value("bar", 6u) != bar)
return;
val = node.attribute_value("size", 0u);
});
device.for_each_sub_node("io_port", [&] (Xml_node node) {
if (node.attribute_value("bar", 6u) != bar)
return;
val = node.attribute_value("size", 0u);
});
});
return val;
}
static unsigned bar_address(Platform::Device const &dev,
Xml_node const &devices, unsigned bar)
{
if (bar > 6)
return 0;
using namespace Genode;
unsigned val = 0;
apply(dev, devices, [&] (Xml_node device) {
device.for_each_sub_node("io_mem", [&] (Xml_node node) {
if (node.attribute_value("bar", 6u) != bar)
return;
val = node.attribute_value("phys_addr", 0u);
});
device.for_each_sub_node("io_port", [&] (Xml_node node) {
if (node.attribute_value("bar", 6u) != bar)
return;
val = node.attribute_value("phys_addr", 0u);
});
});
return val;
}
static unsigned char irq_line(Platform::Device const &dev,
Xml_node const &devices)
{
enum : unsigned char { INVALID_IRQ_LINE = 0xffu };
unsigned char irq = INVALID_IRQ_LINE;
apply(dev, devices, [&] (Xml_node device) {
device.for_each_sub_node("irq", [&] (Xml_node node) {
irq = node.attribute_value("number", (unsigned char)INVALID_IRQ_LINE);
});
});
return irq;
}
Platform::Device::Device(Connection &platform, Type)
: _platform { platform } { }
Platform::Device::Device(Connection &platform, Name name)
:
_platform { platform },
_device_cap { _platform.device_cap(name.string()) },
_name { name }
{
if (!_device_cap.valid()) {
error(__func__, ": could not get device capability");
throw -1;
}
Legacy_platform::Device_client device(_device_cap);
_class_code = device.class_code() >> 8;
}
unsigned Platform::Device::Config_space::read(unsigned char address,
Access_size size)
{
/* 32bit BARs only for now */
if (address >= 0x10 && address <= 0x24) {
unsigned const bar = (address - 0x10) / 4;
if (_device._bar_checked_for_size[bar]) {
_device._bar_checked_for_size[bar] = 0;
return bar_size(_device, *_device._platform._devices_node, bar);
}
return bar_address(_device, *_device._platform._devices_node, bar);
}
/*
* If any PCI device reports 0 as interrupt PIN, drivers may try to force
* MSI setup (e.g., xhci). So, we clamp the interrupt PIN to 1 to let
* drivers finish initialization and don't bother the platform driver.
*/
if (address == 0x3d)
return 0x01;
if (address == 0x3c)
return irq_line(_device, *_device._platform._devices_node);
if (address == 0x34)
return 0u;
Legacy_platform::Device::Access_size const as = convert(size);
Legacy_platform::Device_client device { _device._device_cap };
return device.config_read(address, as);
}
void Platform::Device::Config_space::write(unsigned char address,
unsigned value,
Access_size size)
{
/* 32bit BARs only for now */
if (address >= 0x10 && address <= 0x24) {
unsigned const bar = (address - 0x10) / 4;
if (value == 0xffffffffu)
_device._bar_checked_for_size[bar] = 1;
return;
}
enum {
CLASS_CODE_USB = 0xc03,
};
switch(_device._class_code) {
case CLASS_CODE_USB:
/* reject writes to unknown addresses */
switch (address) {
case 0x04:
/*
* Doing this multiple times induces multiple "assignment of PCI
* device" diasgnostics currently.
*/
/* command register (value for enable io, memory, bus master) */
value = 7;
break;
/*
* Write in [0x40,0xff] should be okay if there are is no capability
* list (status register bit 4 + capability list pointer). Otherwise,
* writes into capability-list entries should be rejected.
*/
case 0xc0: /* UHCI BIOS handoff (UHCI_USBLEGSUP) */ break;
case 0xc4: /* UHCI INTEL resume-enable (USBRES_INTEL) */ break;
case 0x60 ... 0x6f: /* EHCI BIOS handoff (just empiric, address not fixed) */ break;
default:
return;
}
break;
}
Legacy_platform::Device::Access_size const as = convert(size);
Legacy_platform::Device_client device { _device._device_cap };
device.config_write(address, value, as);
}
size_t Platform::Device::Mmio::size() const
{
return _attached_ds.constructed() ? _attached_ds->size() : 0;
}
void *Platform::Device::Mmio::_local_addr()
{
if (!_attached_ds.constructed()) {
Legacy_platform::Device_client device { _device._device_cap };
Cache cache = Cache::UNCACHED;
{
uint8_t phys_bar_id = 0;
/* convert virtual bar id into phys bar id */
for (unsigned virt_id = 0, i = 0; i < 6; i++) {
auto const type = device.resource(i).type();
if (type == Legacy_platform::Device::Resource::Type::MEMORY) {
virt_id ++;
phys_bar_id = uint8_t(i);
}
if (virt_id > _index.value)
break;
}
if (device.resource(phys_bar_id).prefetchable())
cache = Cache::WRITE_COMBINED;
auto const r = device.resource(phys_bar_id);
Range::start = (r.base() & 0xfffu);
}
Io_mem_session_capability io_mem_cap =
device.io_mem(uint8_t(_index.value), cache);
Io_mem_session_client io_mem_client(io_mem_cap);
_attached_ds.construct(Lx_kit::env().env.rm(),
io_mem_client.dataspace());
}
return (void*)(_attached_ds->local_addr<char>() + Range::start);
}
Platform::Device::Io_port_range::Io_port_range(Device &device, Index index)
:
_device { device },
_index { index }
{
Legacy_platform::Device_client client { _device._device_cap };
_io_port.construct(client.io_port((uint8_t)index.value));
}
unsigned char Platform::Device::Io_port_range::inb(uint16_t addr)
{
return _io_port->inb(addr);
}
unsigned short Platform::Device::Io_port_range::inw(uint16_t addr)
{
return _io_port->inw(addr);
}
unsigned int Platform::Device::Io_port_range::inl(uint16_t addr)
{
return _io_port->inl(addr);
}
void Platform::Device::Io_port_range::outb(uint16_t addr, uint8_t val)
{
return _io_port->outb(addr, val);
}
void Platform::Device::Io_port_range::outw(uint16_t addr, uint16_t val)
{
return _io_port->outw(addr, val);
}
void Platform::Device::Io_port_range::outl(uint16_t addr, uint32_t val)
{
return _io_port->outl(addr, val);
}
Platform::Device::Irq::Irq(Platform::Device &device, Index index)
:
_device { device },
_index { index }
{
Legacy_platform::Device_client client { _device._device_cap };
_irq.construct(client.irq((uint8_t)index.value));
}
void Platform::Device::Irq::ack()
{
_irq->ack_irq();
}
void Platform::Device::Irq::sigh(Signal_context_capability sigh)
{
_irq->sigh(sigh);
_irq->ack_irq();
}
void Platform::Device::Irq::sigh_omit_initial_signal(Signal_context_capability sigh)
{
_irq->sigh(sigh);
}
static Platform::Device::Config_space::Access_size access_size(unsigned len)
{
using AS = Platform::Device::Config_space::Access_size;
AS as = AS::ACCESS_8BIT;
if (len == 4) as = AS::ACCESS_32BIT;
else if (len == 2) as = AS::ACCESS_16BIT;
else as = AS::ACCESS_8BIT;
return as;
}
bool Lx_kit::Device::read_config(unsigned reg, unsigned len, unsigned *val)
{
if (!_pdev.constructed())
enable();
if (!val)
return false;
using AS = Platform::Device::Config_space::Access_size;
AS const as = access_size(len);
*val = Platform::Device::Config_space(*_pdev).read((unsigned char)reg, as);
return true;
}
bool Lx_kit::Device::write_config(unsigned reg, unsigned len, unsigned val)
{
if (!_pdev.constructed())
return false;
using AS = Platform::Device::Config_space::Access_size;
AS const as = access_size(len);
Platform::Device::Config_space(*_pdev).write((unsigned char)reg, val, as);
return true;
}

View File

@ -25,11 +25,16 @@ SRC_C += lx_emul/shadow/lib/devres.c
SRC_C += lx_emul/shadow/lib/smp_processor_id.c
SRC_C += lx_emul/shadow/mm/memblock.c
SRC_C += lx_emul/shadow/mm/page_alloc.c
SRC_CC += lx_emul/pci_config_space.cc
SRC_CC += lx_emul/pci_init.cc
SRC_C += lx_emul/shadow/drivers/pci/host-bridge.c
SRC_C += lx_emul/shadow/drivers/pci/pci.c
SRC_C += lx_emul/shadow/drivers/pci/pci-sysfs.c
SRC_C += lx_emul/shadow/drivers/pci/search.c
SRC_C += lx_emul/shadow/drivers/pci/setup-irq.c
SRC_C += lx_emul/shadow/drivers/pci/setup-res.c
SRC_CC += lx_emul/pci.cc
SRC_CC += lx_emul/pci_bus.c
SRC_CC += lx_kit/device.cc
SRC_CC += lx_kit/memory_dma.cc
SRC_CC += lx_kit/spec/x86/platform.cc
SRC_C += lx_emul/shadow/fs/sysfs/dir.c
SRC_C += lx_emul/shadow/fs/sysfs/file.c

View File

@ -25,7 +25,6 @@ SRC_C += lx_socket_call.c
SRC_C += $(notdir $(wildcard $(TARGET_LIB_DIR)/generated_dummies.c))
SRC_C += lx_emul/common_dummies.c
SRC_C += lx_emul/spec/x86/pci.c
CC_C_OPT += -I$(LX_SRC_DIR)/drivers/net/wireless/intel/iwlwifi
CC_C_OPT += -I$(LX_SRC_DIR)/include/linux

View File

@ -2,6 +2,10 @@
# Content hosted in the dde_linux repository
#
content: include/pci
include/pci:
mkdir -p $(dir $@); cp -r $(GENODE_DIR)/repos/os/$@ $(dir $@)
MIRRORED_FROM_DDE_LINUX := src/lib/lx_emul \
src/lib/lx_kit \
src/include/lx_emul \

View File

@ -1,5 +1,6 @@
_/raw/test_usb_host_drv-pc
_/src/acpi_drv
_/src/pci_decode
_/src/pc_usb_host_drv
_/src/platform_drv
_/src/report_rom

View File

@ -15,6 +15,24 @@
<service name="Usb">
<default-policy> <child name="usb_drv"/> </default-policy> </service>
<start name="report_rom" caps="70">
<resource name="RAM" quantum="1M"/>
<provides>
<service name="ROM" />
<service name="Report" />
</provides>
<config>
<policy label="pci_decode -> system" report="acpi_drv -> acpi"/>
<policy label="platform_drv -> devices" report="pci_decode -> devices"/>
</config>
<route>
<service name="LOG"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="ROM"> <parent/> </service>
</route>
</start>
<start name="acpi_drv" caps="250">
<resource name="RAM" quantum="4M"/>
<route>
@ -28,33 +46,27 @@
</route>
</start>
<start name="report_rom" caps="70">
<start name="pci_decode" caps="350">
<resource name="RAM" quantum="1M"/>
<provides>
<service name="ROM" />
<service name="Report" />
</provides>
<config>
<policy label="platform_drv -> acpi" report="acpi_drv -> acpi"/>
</config>
<route>
<service name="LOG"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="Report">
<child name="report_rom"/> </service>
<service name="ROM" label="system">
<child name="report_rom"/> </service>
<service name="IO_MEM"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="RM"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="ROM"> <parent/> </service>
</route>
</start>
<start name="platform_drv" caps="200" managing_system="yes">
<binary name="legacy_pc_platform_drv"/>
<resource name="RAM" quantum="3M"/>
<provides>
<service name="Platform"/>
<service name="Acpi"/>
</provides>
<start name="platform_drv" caps="100" managing_system="yes">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Platform"/> </provides>
<route>
<service name="ROM" label="system"> <child name="report_rom"/> </service>
<service name="ROM" label="acpi"> <child name="report_rom"/> </service>
<service name="ROM" label="devices"> <child name="report_rom"/> </service>
<service name="IRQ"> <parent/> </service>
<service name="IO_MEM"> <parent/> </service>
<service name="IO_PORT"> <parent/> </service>
@ -65,11 +77,11 @@
<service name="Timer"> <parent/> </service>
</route>
<config>
<policy label_prefix="usb_drv"> <pci class="USB"/> </policy>
<policy label_prefix="usb_drv" info="yes"> <pci class="USB"/> </policy>
</config>
</start>
<start name="usb_drv" caps="150">
<start name="usb_drv" caps="200">
<binary name="pc_usb_host_drv"/>
<resource name="RAM" quantum="16M"/>
<provides> <service name="Usb"/> </provides>

View File

@ -19,6 +19,9 @@ set use_top 0
set build_components {
core init timer
drivers/acpi
drivers/platform
app/pci_decode
drivers/framebuffer/intel/pc
test/framebuffer
server/report_rom
@ -31,9 +34,6 @@ set build_components {
append_if $use_gpu build_components { drivers/gpu/intel }
append_if $use_top build_components { app/top }
source ${genode_dir}/repos/base/run/platform_drv.inc
append_platform_drv_build_components
build $build_components
create_boot_directory
@ -58,22 +58,86 @@ append config {
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<default caps="100"/>}
<default caps="100"/>
append_platform_drv_config
<start name="report_rom" caps="70">
<resource name="RAM" quantum="1M"/>
<provides>
<service name="ROM" />
<service name="Report" />
</provides>
<config>
<policy label="pci_decode -> system" report="acpi_drv -> acpi"/>
<policy label="intel_fb_drv -> intel_opregion" report="acpi_drv -> intel_opregion"/>
<policy label="platform_drv -> devices" report="pci_decode -> devices"/>
</config>
<route>
<service name="LOG"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="ROM"> <parent/> </service>
</route>
</start>
<start name="acpi_drv" caps="250">
<resource name="RAM" quantum="4M"/>
<route>
<service name="IO_MEM"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="RM"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="Report"> <child name="report_rom"/> </service>
</route>
</start>
<start name="pci_decode" caps="350">
<resource name="RAM" quantum="1M"/>
<route>
<service name="Report">
<child name="report_rom"/> </service>
<service name="ROM" label="system">
<child name="report_rom"/> </service>
<service name="IO_MEM"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="RM"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="ROM"> <parent/> </service>
</route>
</start>
<start name="platform_drv" caps="100" managing_system="yes">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Platform"/> </provides>
<route>
<service name="ROM" label="devices"> <child name="report_rom"/> </service>
<service name="IRQ"> <parent/> </service>
<service name="IO_MEM"> <parent/> </service>
<service name="IO_PORT"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service>
</route>
<config>
<policy label_prefix="intel_fb_drv" info="yes">
<pci class="VGA"/>
<pci class="ISABRIDGE"/>
</policy>
<policy label_prefix="intel_gpu_drv" info="yes">
<pci class="VGA"/>
<pci class="ISABRIDGE"/>
</policy>
</config>
</start>
append config {
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides><service name="Timer"/></provides>
</start>
<start name="report_rom" priority="0">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Report" /> <service name="ROM" /> </provides>
<config verbose="no"/>
</start>
<start name="init_dynamic" caps="10000">
<binary name="init"/>
<resource name="RAM" quantum="1000M"/>
@ -81,7 +145,7 @@ append config {
<service name="Report"> <child name="report_rom"/> </service>
<service name="Platform"> <child name="platform_drv" label="intel_fb_drv"/> </service>
<service name="ROM" label="intel_fb_drv -> intel_opregion">
<child name="acpi_report_rom" label="intel_fb_drv -> intel_opregion"/>
<child name="report_rom" label="intel_fb_drv -> intel_opregion"/>
</service>
<any-service> <parent/> <any-child/> </any-service>
</route>
@ -221,13 +285,12 @@ install_config $config
set boot_modules {
core ld.lib.so init timer pc_intel_fb_drv intel_fb_controller
test-framebuffer report_rom fs_rom vfs vfs.lib.so vfs_import.lib.so
platform_drv acpi_drv pci_decode
}
append_if $use_gpu boot_modules { intel_gpu_drv }
append_if $use_top boot_modules { top }
append_platform_drv_boot_modules
build_boot_image $boot_modules
if { [get_cmd_switch --autopilot] } {

View File

@ -65,6 +65,9 @@ assert_spec x86
set build_components {
core init timer
app/pci_decode
drivers/acpi
drivers/platform
drivers/rtc
drivers/wifi/pc
server/report_rom
@ -76,9 +79,6 @@ set build_components {
lib/vfs_lwip
}
source ${genode_dir}/repos/base/run/platform_drv.inc
append_platform_drv_build_components
build $build_components
create_boot_directory
@ -108,6 +108,73 @@ append config {
<provides> <service name="Timer"/> </provides>
</start>
<start name="report_rom" caps="70">
<resource name="RAM" quantum="1M"/>
<provides>
<service name="ROM" />
<service name="Report" />
</provides>
<config verbose="yes">
<policy label="pci_decode -> system" report="acpi_drv -> acpi"/>
<policy label="platform_drv -> devices" report="pci_decode -> devices"/>
</config>
<route>
<service name="LOG"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="ROM"> <parent/> </service>
</route>
</start>
<start name="acpi_drv" caps="250">
<resource name="RAM" quantum="4M"/>
<route>
<service name="IO_MEM"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="RM"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="Report"> <child name="report_rom"/> </service>
</route>
</start>
<start name="pci_decode" caps="350">
<resource name="RAM" quantum="1M"/>
<route>
<service name="Report">
<child name="report_rom"/> </service>
<service name="ROM" label="system">
<child name="report_rom"/> </service>
<service name="IO_MEM"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="RM"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="ROM"> <parent/> </service>
</route>
</start>
<start name="platform_drv" caps="100" managing_system="yes">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Platform"/> </provides>
<route>
<service name="ROM" label="devices"> <child name="report_rom"/> </service>
<service name="IRQ"> <parent/> </service>
<service name="IO_MEM"> <parent/> </service>
<service name="IO_PORT"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service>
</route>
<config>
<policy label_prefix="wifi_drv" info="yes">
<pci class="WIFI"/>
</policy>
</config>
</start>
<start name="rtc_drv">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Rtc"/> </provides>
@ -227,11 +294,6 @@ append config {
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
}
append_platform_drv_config
append config {
</config>
}
@ -267,15 +329,13 @@ set boot_modules {
wpa_driver_nl80211.lib.so wpa_supplicant.lib.so
pc_wifi_drv wifi.lib.so vfs_wifi.lib.so
nic_router
platform_drv acpi_drv pci_decode
test-lwip_httpsrv
vfs_lwip.lib.so
}
append boot_modules $firmware_modules
append_platform_drv_boot_modules
build_boot_image $boot_modules
run_genode_until forever

View File

@ -547,3 +547,33 @@ int wbinvd_on_all_cpus(void)
lx_emul_trace(__func__);
return 0;
}
void srcu_drive_gp(struct work_struct *wp);
void srcu_drive_gp(struct work_struct *wp)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/pci.h>
int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn,
int where, u8 *val)
{
lx_emul_trace_and_stop(__func__);
}
int pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn,
int where, u16 *val)
{
lx_emul_trace_and_stop(__func__);
}
int pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn,
int where, u8 val)
{
lx_emul_trace_and_stop(__func__);
}

View File

@ -29,3 +29,22 @@ void emul_free_shmem_file_buffer(void *addr)
{
Lx_kit::env().memory.free_buffer(addr);
}
unsigned short emul_intel_gmch_control_reg()
{
using namespace Genode;
unsigned short ret = 0;
Lx_kit::env().devices.with_xml([&] (Xml_node node) {
node.for_each_sub_node("device", [&] (Xml_node node) {
node.for_each_sub_node("pci-config", [&] (Xml_node node) {
unsigned short gmch =
node.attribute_value<unsigned short>("intel_gmch_control", 0U);
if (gmch) ret = gmch;
});
});
});
return ret;
}

View File

@ -1,7 +1,7 @@
/*
* \brief Dummy definitions of Linux Kernel functions
* \author Automatically generated file - do no edit
* \date 2022-06-24
* \date 2022-07-28
*/
#include <lx_emul.h>
@ -1525,14 +1525,6 @@ void mark_page_accessed(struct page * page)
}
#include <linux/kernel.h>
unsigned long long memparse(const char * ptr,char ** retptr)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/io.h>
void memunmap(void * addr)
@ -1646,7 +1638,7 @@ enum reboot_mode panic_reboot_mode;
#include <linux/pci.h>
void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge)
int pci_dev_present(const struct pci_device_id * ids)
{
lx_emul_trace_and_stop(__func__);
}
@ -1654,14 +1646,7 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge)
#include <linux/pci.h>
void pci_assign_unassigned_bus_resources(struct pci_bus * bus)
{
lx_emul_trace_and_stop(__func__);
}
extern unsigned long pci_cardbus_resource_alignment(struct resource * res);
unsigned long pci_cardbus_resource_alignment(struct resource * res)
void pci_disable_device(struct pci_dev * dev)
{
lx_emul_trace_and_stop(__func__);
}
@ -1669,11 +1654,7 @@ unsigned long pci_cardbus_resource_alignment(struct resource * res)
#include <linux/pci.h>
unsigned int pci_flags;
extern int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout);
int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout)
int pci_read_config_byte(const struct pci_dev * dev,int where,u8 * val)
{
lx_emul_trace_and_stop(__func__);
}
@ -1681,28 +1662,7 @@ int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout)
#include <linux/pci.h>
int pci_mmap_resource_range(struct pci_dev * pdev,int bar,struct vm_area_struct * vma,enum pci_mmap_state mmap_state,int write_combine)
{
lx_emul_trace_and_stop(__func__);
}
extern void __init pci_realloc_get_opt(char * str);
void __init pci_realloc_get_opt(char * str)
{
lx_emul_trace_and_stop(__func__);
}
extern void pci_restore_vc_state(struct pci_dev * dev);
void pci_restore_vc_state(struct pci_dev * dev)
{
lx_emul_trace_and_stop(__func__);
}
extern int pci_save_vc_state(struct pci_dev * dev);
int pci_save_vc_state(struct pci_dev * dev)
int pci_save_state(struct pci_dev * dev)
{
lx_emul_trace_and_stop(__func__);
}
@ -1710,42 +1670,23 @@ int pci_save_vc_state(struct pci_dev * dev)
#include <linux/pci.h>
void pci_stop_and_remove_bus_device_locked(struct pci_dev * dev)
int pci_set_power_state(struct pci_dev * dev,pci_power_t state)
{
lx_emul_trace_and_stop(__func__);
}
extern void pci_vpd_release(struct pci_dev * dev);
void pci_vpd_release(struct pci_dev * dev)
#include <linux/pci.h>
void pci_unmap_rom(struct pci_dev * pdev,void __iomem * rom)
{
lx_emul_trace_and_stop(__func__);
}
extern unsigned int pcibios_assign_all_busses(void);
unsigned int pcibios_assign_all_busses(void)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/pci.h>
extern void pcie_aspm_init_link_state(struct pci_dev * pdev);
void pcie_aspm_init_link_state(struct pci_dev * pdev)
{
lx_emul_trace_and_stop(__func__);
}
extern void pcie_aspm_pm_state_change(struct pci_dev * pdev);
void pcie_aspm_pm_state_change(struct pci_dev * pdev)
{
lx_emul_trace_and_stop(__func__);
}
extern void pcie_aspm_powersave_config_link(struct pci_dev * pdev);
void pcie_aspm_powersave_config_link(struct pci_dev * pdev)
int pci_write_config_byte(const struct pci_dev * dev,int where,u8 val)
{
lx_emul_trace_and_stop(__func__);
}
@ -1789,14 +1730,6 @@ void put_pid(struct pid * pid)
}
#include <linux/pci.h>
int raw_pci_read(unsigned int domain,unsigned int bus,unsigned int devfn,int reg,int len,u32 * val)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/reboot.h>
enum reboot_mode reboot_mode;
@ -1899,7 +1832,7 @@ void * skb_put(struct sk_buff * skb,unsigned int len)
#include <linux/smp.h>
int smp_call_function_single(int cpu,void (* func)(void * info),void * info,int wait)
int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait)
{
lx_emul_trace_and_stop(__func__);
}
@ -2016,3 +1949,4 @@ void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task)
{
lx_emul_trace_and_stop(__func__);
}

View File

@ -28,21 +28,16 @@ struct dma_fence_work_ops;
void lx_emul_time_udelay(unsigned long usec);
/* shadow/asm/io.h */
void lx_emul_io_port_outb(unsigned char value, unsigned short port);
void lx_emul_io_port_outw(unsigned short value, unsigned short port);
void lx_emul_io_port_outl(unsigned int value, unsigned short port);
unsigned char lx_emul_io_port_inb(unsigned short port);
unsigned short lx_emul_io_port_inw(unsigned short port);
unsigned int lx_emul_io_port_inl(unsigned short port);
void *emul_alloc_shmem_file_buffer(unsigned long);
void * intel_io_mem_map(unsigned long offset, unsigned long size);
#include "lx_i915.h"
unsigned short emul_intel_gmch_control_reg(void);
enum { OPREGION_PSEUDO_PHYS_ADDR = 0xffffefff };
#ifdef __cplusplus
}
#endif

View File

@ -1,20 +0,0 @@
/*
* \brief Misc
* \author Josef Soentgen
* \date 2022-01-20
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
/* Genode includes */
#include <os/backtrace.h>
extern "C" void lx_backtrace(void)
{
Genode::backtrace();
}

View File

@ -21,6 +21,7 @@
#include <rm_session/connection.h>
#include <rom_session/connection.h>
#include <lx_emul.h>
extern "C" void * intel_io_mem_map(unsigned long const phys,
unsigned long const size)
@ -51,12 +52,16 @@ extern "C" void * intel_io_mem_map(unsigned long const phys,
}
}
if ((opregion_start <= phys) &&
(phys + size <= opregion_start + opregion_size)) {
/*
* we have to substract the pseudo physical address
* we returned when reading the ASLS from config space
*/
addr_t offset = phys - OPREGION_PSEUDO_PHYS_ADDR;
if ((offset + size) <= opregion_size) {
try {
auto ptr = ((addr_t)rom_opregion->local_addr<void>())
+ (phys - opregion_start) + (phys & 0xffful);
+ offset + (opregion_start & 0xffful);
return (void *)ptr;
} catch (...) {
error("Intel opregion lookup failed");

View File

@ -0,0 +1,140 @@
/*
* \brief Additional PCI functions needed by Intel graphics driver
* \author Stefan Kalkowski
* \author Josef Soentgen
* \date 2022-07-27
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <lx_emul.h>
#include <lx_emul/io_mem.h>
#include <lx_emul/pci.h>
#include <linux/pci.h>
#include <drm/i915_drm.h>
#include <../drivers/gpu/drm/i915/i915_reg.h>
#undef GFX_FLSH_CNTL /* suppress warning of double define */
#include <../drivers/char/agp/intel-agp.h>
unsigned long pci_mem_start = 0xaeedbabe;
int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
resource_size_t size, resource_size_t align,
resource_size_t min, unsigned long type_mask,
resource_size_t (*alignf)(void *,
const struct resource *,
resource_size_t,
resource_size_t),
void *alignf_data)
{
return -1;
}
void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
{
struct resource *r;
unsigned long phys_addr;
unsigned long size;
if (!dev || bar > 5) {
printk("%s:%d: invalid request for dev: %p bar: %d\n",
__func__, __LINE__, dev, bar);
return NULL;
}
printk("pci_iomap: request for dev: %s bar: %d\n", dev_name(&dev->dev), bar);
r = &dev->resource[bar];
phys_addr = r->start;
size = r->end - r->start;
if (!phys_addr || !size)
return NULL;
return lx_emul_io_mem_map(phys_addr, size);
}
void __iomem * pci_map_rom(struct pci_dev * pdev,size_t * size)
{
/*
* Needed for VBT access which we do not allow
*/
return NULL;
}
int pci_read_config_word(const struct pci_dev * dev, int where, u16 *val)
{
switch (where) {
/* Intel graphics and memory controller hub control register */
/* I830_GMCH_CTRL is identical to INTEL_GMCH_CTRL */
case SNB_GMCH_CTRL:
case INTEL_GMCH_CTRL:
*val = emul_intel_gmch_control_reg();
return 0;
case SWSCI: /* intel_fb: software smi sci */
*val = 0;
return 0;
};
printk("%s: %s %d %d\n", __func__, dev_name(&dev->dev), dev->devfn, where);
lx_emul_trace_and_stop(__func__);
}
int pci_read_config_dword(const struct pci_dev * dev, int where, u32 *val)
{
switch (where) {
case MCHBAR_I915:
case MCHBAR_I965:
*val = 0x1; /* return ENABLE bit being set */
return 0;
case I965_IFPADDR: /* intel host bridge flush page (lower) */
case I965_IFPADDR + 4: /* intel host bridge flush page (higher) */
*val = 0;
return 0;
case ASLS:
/*
* we just use a physical address as token here,
* hopefully it never crashes with other I/O memory addresses
*/
*val = OPREGION_PSEUDO_PHYS_ADDR;
return 0;
};
lx_emul_trace_and_stop(__func__);
}
int pci_write_config_word(const struct pci_dev * dev, int where, u16 val)
{
switch (where) {
case SWSCI: /* intel_fb: software smi sci */
/* just ignore */
return 0;
};
lx_emul_trace_and_stop(__func__);
}
int pci_write_config_dword(const struct pci_dev * dev, int where, u32 val)
{
switch (where) {
case I965_IFPADDR: /* intel host bridge flush page (lower) */
case I965_IFPADDR + 4: /* intel host bridge flush page (higher) */
/* just ignore */
return 0;
};
lx_emul_trace_and_stop(__func__);
}

View File

@ -1,5 +1,4 @@
arch/x86/lib/hweight.S
arch/x86/pci/legacy.c
arch/x86/platform/intel/iosf_mbi.c
drivers/base/bus.c
drivers/base/class.c
@ -183,19 +182,7 @@ drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/i2c-boardinfo.c
drivers/i2c/i2c-core-acpi.c
drivers/i2c/i2c-core-base.c
drivers/pci/access.c
drivers/pci/bus.c
drivers/pci/host-bridge.c
drivers/pci/msi.c
drivers/pci/pci-driver.c
drivers/pci/pci-label.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/probe.c
drivers/pci/rom.c
drivers/pci/search.c
drivers/pci/setup-res.c
drivers/pci/slot.c
drivers/video/backlight/backlight.c
drivers/video/fbdev/core/fb_notify.c
drivers/video/fbdev/core/fbcmap.c
@ -257,7 +244,6 @@ lib/kstrtox.c
lib/list_sort.c
lib/llist.c
lib/math/div64.c
lib/pci_iomap.c
lib/radix-tree.c
lib/rbtree.c
lib/refcount.c

View File

@ -2,7 +2,6 @@ arch/x86/lib/hweight.S
arch/x86/lib/memcpy_64.S
arch/x86/lib/memmove_64.S
arch/x86/lib/memset_64.S
arch/x86/pci/legacy.c
arch/x86/platform/intel/iosf_mbi.c
drivers/base/bus.c
drivers/base/class.c
@ -186,19 +185,7 @@ drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/i2c-boardinfo.c
drivers/i2c/i2c-core-acpi.c
drivers/i2c/i2c-core-base.c
drivers/pci/access.c
drivers/pci/bus.c
drivers/pci/host-bridge.c
drivers/pci/msi.c
drivers/pci/pci-driver.c
drivers/pci/pci-label.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/probe.c
drivers/pci/rom.c
drivers/pci/search.c
drivers/pci/setup-res.c
drivers/pci/slot.c
drivers/video/backlight/backlight.c
drivers/video/fbdev/core/fb_notify.c
drivers/video/fbdev/core/fbcmap.c
@ -259,7 +246,6 @@ lib/kobject_uevent.c
lib/kstrtox.c
lib/list_sort.c
lib/llist.c
lib/pci_iomap.c
lib/radix-tree.c
lib/rbtree.c
lib/refcount.c

View File

@ -9,21 +9,21 @@ INC_DIR += $(REL_PRG_DIR)
INC_DIR += $(REL_PRG_DIR)/shadow
SRC_CC += main.cc
SRC_CC += misc.cc
SRC_CC += emul.cc
SRC_CC += time.cc
SRC_CC += opregion_io_mem.cc
SRC_C += dummies.c
SRC_C += pci.c
SRC_C += lx_emul.c
SRC_C += $(notdir $(wildcard $(REL_PRG_DIR)/generated_dummies.c))
SRC_C += fb.c
SRC_C += lx_user.c
SRC_C += gem.c
SRC_C += lx_emul/common_dummies.c
SRC_C += lx_emul/spec/x86/pci.c
SRC_C += lx_emul/shadow/mm/page_alloc.c
SRC_C += lx_emul/shadow/drivers/char/random.c
vpath %.c $(REL_PRG_DIR)
vpath %.c $(REL_PRG_DIR)
vpath %.cc $(REL_PRG_DIR)
vpath %.c $(REP_DIR)/src/lib/pc

View File

@ -90,3 +90,11 @@ u32 prandom_u32(void)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/pci.h>
void pci_disable_device(struct pci_dev * dev)
{
lx_emul_trace(__func__);
}

View File

@ -1,7 +1,7 @@
/*
* \brief Dummy definitions of Linux Kernel functions
* \author Automatically generated file - do no edit
* \date 2022-05-06
* \date 2022-07-29
*/
#include <lx_emul.h>
@ -301,14 +301,6 @@ int kobject_uevent_env(struct kobject * kobj,enum kobject_action action,char * e
}
#include <linux/kernel.h>
unsigned long long memparse(const char * ptr,char ** retptr)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/irq.h>
struct irq_chip no_irq_chip;
@ -348,7 +340,7 @@ int param_set_copystring(const char * val,const struct kernel_param * kp)
#include <linux/pci.h>
void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge)
void pci_clear_mwi(struct pci_dev * dev)
{
lx_emul_trace_and_stop(__func__);
}
@ -356,14 +348,7 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge)
#include <linux/pci.h>
void pci_assign_unassigned_bus_resources(struct pci_bus * bus)
{
lx_emul_trace_and_stop(__func__);
}
extern unsigned long pci_cardbus_resource_alignment(struct resource * res);
unsigned long pci_cardbus_resource_alignment(struct resource * res)
struct pci_dev * pci_get_slot(struct pci_bus * bus,unsigned int devfn)
{
lx_emul_trace_and_stop(__func__);
}
@ -371,11 +356,7 @@ unsigned long pci_cardbus_resource_alignment(struct resource * res)
#include <linux/pci.h>
unsigned int pci_flags;
extern int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout);
int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout)
int pci_set_power_state(struct pci_dev * dev,pci_power_t state)
{
lx_emul_trace_and_stop(__func__);
}
@ -383,71 +364,7 @@ int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout)
#include <linux/pci.h>
int pci_mmap_resource_range(struct pci_dev * pdev,int bar,struct vm_area_struct * vma,enum pci_mmap_state mmap_state,int write_combine)
{
lx_emul_trace_and_stop(__func__);
}
extern void __init pci_realloc_get_opt(char * str);
void __init pci_realloc_get_opt(char * str)
{
lx_emul_trace_and_stop(__func__);
}
extern void pci_restore_vc_state(struct pci_dev * dev);
void pci_restore_vc_state(struct pci_dev * dev)
{
lx_emul_trace_and_stop(__func__);
}
extern int pci_save_vc_state(struct pci_dev * dev);
int pci_save_vc_state(struct pci_dev * dev)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/pci.h>
void pci_stop_and_remove_bus_device_locked(struct pci_dev * dev)
{
lx_emul_trace_and_stop(__func__);
}
extern void pci_vpd_release(struct pci_dev * dev);
void pci_vpd_release(struct pci_dev * dev)
{
lx_emul_trace_and_stop(__func__);
}
extern unsigned int pcibios_assign_all_busses(void);
unsigned int pcibios_assign_all_busses(void)
{
lx_emul_trace_and_stop(__func__);
}
extern void pcie_aspm_init_link_state(struct pci_dev * pdev);
void pcie_aspm_init_link_state(struct pci_dev * pdev)
{
lx_emul_trace_and_stop(__func__);
}
extern void pcie_aspm_pm_state_change(struct pci_dev * pdev);
void pcie_aspm_pm_state_change(struct pci_dev * pdev)
{
lx_emul_trace_and_stop(__func__);
}
extern void pcie_aspm_powersave_config_link(struct pci_dev * pdev);
void pcie_aspm_powersave_config_link(struct pci_dev * pdev)
int pci_write_config_dword(const struct pci_dev * dev,int where,u32 val)
{
lx_emul_trace_and_stop(__func__);
}
@ -469,14 +386,6 @@ void put_pid(struct pid * pid)
}
#include <linux/pci.h>
int raw_pci_read(unsigned int domain,unsigned int bus,unsigned int devfn,int reg,int len,u32 * val)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/refcount.h>
bool refcount_dec_not_one(refcount_t * r)
@ -511,7 +420,7 @@ void seq_printf(struct seq_file * m,const char * f,...)
#include <linux/smp.h>
int smp_call_function_single(int cpu,void (* func)(void * info),void * info,int wait)
int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait)
{
lx_emul_trace_and_stop(__func__);
}
@ -572,3 +481,4 @@ void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task)
{
lx_emul_trace_and_stop(__func__);
}

View File

@ -12,3 +12,76 @@
*/
#include <lx_emul.h>
#include <linux/pci.h>
void __iomem * pci_ioremap_bar(struct pci_dev * pdev, int bar)
{
struct resource *res = &pdev->resource[bar];
return ioremap(res->start, resource_size(res));
}
enum {
UHCI_USBLEGSUP = 0xc0,
UHCI_USBRES_INTEL = 0xc4,
EHCI_SERIAL_BUS_RELEASE = 0x60,
EHCI_PORT_WAKE = 0x62,
};
int pci_read_config_byte(const struct pci_dev * dev,int where,u8 * val)
{
switch (where) {
case EHCI_SERIAL_BUS_RELEASE:
*val = 0x20;
return 0;
};
lx_emul_trace_and_stop(__func__);
}
int pci_read_config_word(const struct pci_dev * dev,int where,u16 * val)
{
switch (where) {
case PCI_COMMAND:
*val = 0x7;
return 0;
case EHCI_PORT_WAKE:
*val = 0;
return 0;
case UHCI_USBLEGSUP:
/* force the driver to do a full_reset */
*val = 0xffff;
return 0;
};
lx_emul_trace_and_stop(__func__);
}
int pci_read_config_dword(const struct pci_dev * dev,int where,u32 * val)
{
*val = 0;
return 0;
}
int pci_write_config_byte(const struct pci_dev * dev,int where,u8 val)
{
switch (where) {
case UHCI_USBRES_INTEL:
/* do nothing */
return 0;
}
lx_emul_trace_and_stop(__func__);
}
int pci_write_config_word(const struct pci_dev * dev,int where,u16 val)
{
switch (where) {
case UHCI_USBLEGSUP:
/* do nothing */
return 0;
}
lx_emul_trace_and_stop(__func__);
}

View File

@ -24,8 +24,6 @@
extern "C" {
#endif
void lx_backtrace(void);
void lx_emul_time_udelay(unsigned long usec);
#ifdef __cplusplus

View File

@ -1,5 +1,4 @@
arch/x86/lib/hweight.S
arch/x86/pci/legacy.c
drivers/base/bus.c
drivers/base/class.c
drivers/base/component.c
@ -10,18 +9,7 @@ drivers/base/driver.c
drivers/base/platform.c
drivers/base/property.c
drivers/clk/clk-devres.c
drivers/pci/access.c
drivers/pci/bus.c
drivers/pci/host-bridge.c
drivers/pci/msi.c
drivers/pci/pci-driver.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/probe.c
drivers/pci/rom.c
drivers/pci/search.c
drivers/pci/setup-res.c
drivers/pci/slot.c
drivers/usb/common/common.c
drivers/usb/common/debug.c
drivers/usb/core/buffer.c
@ -110,7 +98,6 @@ lib/kobject.c
lib/kstrtox.c
lib/list_sort.c
lib/math/div64.c
lib/pci_iomap.c
lib/radix-tree.c
lib/rbtree.c
lib/scatterlist.c

View File

@ -1,5 +1,4 @@
arch/x86/lib/hweight.S
arch/x86/pci/legacy.c
drivers/base/bus.c
drivers/base/class.c
drivers/base/component.c
@ -10,18 +9,7 @@ drivers/base/driver.c
drivers/base/platform.c
drivers/base/property.c
drivers/clk/clk-devres.c
drivers/pci/access.c
drivers/pci/bus.c
drivers/pci/host-bridge.c
drivers/pci/msi.c
drivers/pci/pci-driver.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/probe.c
drivers/pci/rom.c
drivers/pci/search.c
drivers/pci/setup-res.c
drivers/pci/slot.c
drivers/usb/common/common.c
drivers/usb/common/debug.c
drivers/usb/core/buffer.c
@ -109,7 +97,6 @@ lib/klist.c
lib/kobject.c
lib/kstrtox.c
lib/list_sort.c
lib/pci_iomap.c
lib/radix-tree.c
lib/rbtree.c
lib/scatterlist.c

View File

@ -7,15 +7,14 @@ LIBS := base pc_lx_emul jitterentropy
INC_DIR += $(REL_PRG_DIR)
SRC_CC += main.cc
SRC_CC += misc.cc
SRC_CC += time.cc
SRC_CC += lx_emul/shared_dma_buffer.cc
SRC_C += dummies.c
SRC_C += lx_emul.c
SRC_C += $(notdir $(wildcard $(REL_PRG_DIR)/generated_dummies.c))
SRC_C += common_dummies.c
SRC_C += lx_emul/spec/x86/pci.c
SRC_C += lx_emul/usb.c
SRC_C += lx_emul/shadow/lib/kobject_uevent.c
vpath %.c $(REP_DIR)/src/lib/pc
vpath %.cc $(REP_DIR)/src/lib/pc

View File

@ -1,22 +0,0 @@
/**
* \brief PCI fixup calls to execute
* \author Josef Soentgen
* \date 2022-02-07
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _LX_EMUL__PCI_FIXUPS_H_
#define _LX_EMUL__PCI_FIXUPS_H_
static const char * lx_emul_pci_final_fixups[] = {
"__pci_fixup_final_quirk_usb_early_handoff",
"END_OF_PCI_FIXUPS"
};
#endif /* _LX_EMUL__PCI_FIXUPS_H_ */

View File

@ -244,6 +244,39 @@ bool pciehp_is_native(struct pci_dev *bridge)
}
void pci_lock_rescan_remove(void)
{
lx_emul_trace(__func__);
}
void pci_unlock_rescan_remove(void)
{
lx_emul_trace(__func__);
}
bool pci_pme_capable(struct pci_dev *dev, pci_power_t state)
{
lx_emul_trace(__func__);
return false;
}
int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val)
{
lx_emul_trace(__func__);
return -1;
}
u16 pci_find_ext_capability(struct pci_dev *dev, int cap)
{
lx_emul_trace(__func__);
return 0;
}
#include <linux/thermal.h>
struct thermal_cooling_device *thermal_cooling_device_register(const char *s,

View File

@ -1,7 +1,7 @@
/*
* \brief Dummy definitions of Linux Kernel functions
* \author Automatically generated file - do no edit
* \date 2022-06-24
* \date 2022-07-29
*/
#include <lx_emul.h>
@ -639,14 +639,6 @@ int kobject_synth_uevent(struct kobject * kobj,const char * buf,size_t count)
}
#include <linux/kernel.h>
unsigned long long memparse(const char * ptr,char ** retptr)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/preempt.h>
void migrate_disable(void)
@ -712,63 +704,7 @@ enum reboot_mode panic_reboot_mode;
#include <linux/pci.h>
void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/pci.h>
void pci_assign_unassigned_bus_resources(struct pci_bus * bus)
{
lx_emul_trace_and_stop(__func__);
}
extern unsigned long pci_cardbus_resource_alignment(struct resource * res);
unsigned long pci_cardbus_resource_alignment(struct resource * res)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/pci.h>
unsigned int pci_flags;
extern int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout);
int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/pci.h>
int pci_mmap_resource_range(struct pci_dev * pdev,int bar,struct vm_area_struct * vma,enum pci_mmap_state mmap_state,int write_combine)
{
lx_emul_trace_and_stop(__func__);
}
extern void __init pci_realloc_get_opt(char * str);
void __init pci_realloc_get_opt(char * str)
{
lx_emul_trace_and_stop(__func__);
}
extern void pci_restore_vc_state(struct pci_dev * dev);
void pci_restore_vc_state(struct pci_dev * dev)
{
lx_emul_trace_and_stop(__func__);
}
extern int pci_save_vc_state(struct pci_dev * dev);
int pci_save_vc_state(struct pci_dev * dev)
int pci_read_config_dword(const struct pci_dev * dev,int where,u32 * val)
{
lx_emul_trace_and_stop(__func__);
}
@ -784,42 +720,7 @@ void pci_stop_and_remove_bus_device(struct pci_dev * dev)
#include <linux/pci.h>
void pci_stop_and_remove_bus_device_locked(struct pci_dev * dev)
{
lx_emul_trace_and_stop(__func__);
}
extern void pci_vpd_release(struct pci_dev * dev);
void pci_vpd_release(struct pci_dev * dev)
{
lx_emul_trace_and_stop(__func__);
}
extern unsigned int pcibios_assign_all_busses(void);
unsigned int pcibios_assign_all_busses(void)
{
lx_emul_trace_and_stop(__func__);
}
extern void pcie_aspm_init_link_state(struct pci_dev * pdev);
void pcie_aspm_init_link_state(struct pci_dev * pdev)
{
lx_emul_trace_and_stop(__func__);
}
extern void pcie_aspm_pm_state_change(struct pci_dev * pdev);
void pcie_aspm_pm_state_change(struct pci_dev * pdev)
{
lx_emul_trace_and_stop(__func__);
}
extern void pcie_aspm_powersave_config_link(struct pci_dev * pdev);
void pcie_aspm_powersave_config_link(struct pci_dev * pdev)
int pci_write_config_word(const struct pci_dev * dev,int where,u16 val)
{
lx_emul_trace_and_stop(__func__);
}
@ -889,14 +790,6 @@ void put_unused_fd(unsigned int fd)
}
#include <linux/pci.h>
int raw_pci_read(unsigned int domain,unsigned int bus,unsigned int devfn,int reg,int len,u32 * val)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/reboot.h>
enum reboot_mode reboot_mode;
@ -1112,7 +1005,7 @@ int sk_reuseport_attach_filter(struct sock_fprog * fprog,struct sock * sk)
#include <linux/smp.h>
int smp_call_function_single(int cpu,void (* func)(void * info),void * info,int wait)
int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait)
{
lx_emul_trace_and_stop(__func__);
}

View File

@ -574,3 +574,33 @@ void kvfree_call_rcu(struct rcu_head * head,rcu_callback_t func)
void *ptr = (void *) head - (unsigned long) func;
kvfree(ptr);
}
#include <linux/pci.h>
#include <uapi/linux/pci_regs.h>
int pci_write_config_byte(const struct pci_dev * dev,int where,u8 val)
{
enum { PCI_CFG_RETRY_TIMEOUT = 0x41 };
switch (where) {
/*
* iwlwifi: "We disable the RETRY_TIMEOUT register (0x41) to keep
* PCI Tx retries from interfering with C3 CPU state"
*/
case PCI_CFG_RETRY_TIMEOUT:
return 0;
};
lx_emul_trace_and_stop(__func__);
}
int pci_read_config_word(const struct pci_dev * dev,int where,u16 * val)
{
switch (where) {
case PCI_COMMAND:
*val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
return 0;
};
lx_emul_trace_and_stop(__func__);
}

View File

@ -1,5 +1,4 @@
arch/x86/lib/hweight.S
arch/x86/pci/legacy.c
certs/common.c
crypto/acompress.c
crypto/aead.c
@ -117,18 +116,7 @@ drivers/net/wireless/intel/iwlwifi/pcie/trans.c
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
drivers/net/wireless/intel/iwlwifi/pcie/tx.c
drivers/net/wireless/intel/iwlwifi/queue/tx.c
drivers/pci/access.c
drivers/pci/bus.c
drivers/pci/host-bridge.c
drivers/pci/msi.c
drivers/pci/pci-driver.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/probe.c
drivers/pci/rom.c
drivers/pci/search.c
drivers/pci/setup-res.c
drivers/pci/slot.c
fs/nls/nls_base.c
kernel/irq/chip.c
kernel/irq/devres.c
@ -187,7 +175,6 @@ lib/kstrtox.c
lib/list_sort.c
lib/math/div64.c
lib/nlattr.c
lib/pci_iomap.c
lib/radix-tree.c
lib/rbtree.c
lib/refcount.c

View File

@ -1,5 +1,4 @@
arch/x86/lib/hweight.S
arch/x86/pci/legacy.c
certs/common.c
crypto/acompress.c
crypto/aead.c
@ -117,18 +116,7 @@ drivers/net/wireless/intel/iwlwifi/pcie/trans.c
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
drivers/net/wireless/intel/iwlwifi/pcie/tx.c
drivers/net/wireless/intel/iwlwifi/queue/tx.c
drivers/pci/access.c
drivers/pci/bus.c
drivers/pci/host-bridge.c
drivers/pci/msi.c
drivers/pci/pci-driver.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/probe.c
drivers/pci/rom.c
drivers/pci/search.c
drivers/pci/setup-res.c
drivers/pci/slot.c
fs/nls/nls_base.c
kernel/irq/chip.c
kernel/irq/devres.c
@ -186,7 +174,6 @@ lib/kobject.c
lib/kstrtox.c
lib/list_sort.c
lib/nlattr.c
lib/pci_iomap.c
lib/radix-tree.c
lib/rbtree.c
lib/refcount.c

View File

@ -40,6 +40,15 @@ int ___ratelimit(struct ratelimit_state * rs, const char * func)
return 1;
}
#include <linux/sched.h>
long io_schedule_timeout(long timeout)
{
lx_emul_trace_and_stop(__func__);
}
void register_syscore_ops(struct syscore_ops * ops)
{
lx_emul_trace(__func__);

View File

@ -1,7 +1,7 @@
/*
* \brief Dummy definitions of Linux Kernel functions
* \author Automatically generated file - do no edit
* \date 2022-05-06
* \date 2022-09-27
*/
#include <lx_emul.h>
@ -23,6 +23,14 @@ const char * __clk_get_name(const struct clk * clk)
}
#include <linux/sched/task.h>
void __put_task_struct(struct task_struct * tsk)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/srcu.h>
void __srcu_read_unlock(struct srcu_struct * ssp,int idx)
@ -31,49 +39,9 @@ void __srcu_read_unlock(struct srcu_struct * ssp,int idx)
}
#include <linux/printk.h>
#include <linux/uaccess.h>
int printk_deferred(const char * fmt,...)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/irq_work.h>
void irq_work_tick(void)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/printk.h>
asmlinkage __visible void dump_stack(void)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/sched.h>
int io_schedule_prepare(void)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/sched.h>
void io_schedule_finish(int token)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/sched.h>
long io_schedule_timeout(long timeout)
unsigned long _copy_to_user(void __user * to,const void * from,unsigned long n)
{
lx_emul_trace_and_stop(__func__);
}
@ -88,15 +56,47 @@ void ack_bad_irq(unsigned int irq)
#include <linux/kobject.h>
int kobject_synth_uevent(struct kobject * kobj,const char * buf,size_t count)
int add_uevent_var(struct kobj_uevent_env * env,const char * format,...)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/kobject.h>
#include <linux/printk.h>
int add_uevent_var(struct kobj_uevent_env * env,const char * format,...)
asmlinkage __visible void dump_stack(void)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/capability.h>
bool file_ns_capable(const struct file * file,struct user_namespace * ns,int cap)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/property.h>
void fwnode_remove_software_node(struct fwnode_handle * fwnode)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/kernel.h>
int get_option(char ** str,int * pint)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/pseudo_fs.h>
struct pseudo_fs_context * init_pseudo(struct fs_context * fc,unsigned long magic)
{
lx_emul_trace_and_stop(__func__);
}
@ -107,9 +107,36 @@ int add_uevent_var(struct kobj_uevent_env * env,const char * format,...)
bool initcall_debug;
#include <linux/irq.h>
#include <linux/sched.h>
struct irq_chip no_irq_chip;
void io_schedule_finish(int token)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/sched.h>
int io_schedule_prepare(void)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/irq_work.h>
void irq_work_tick(void)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/property.h>
bool is_software_node(const struct fwnode_handle * fwnode)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/kobject.h>
@ -125,49 +152,30 @@ void kill_anon_super(struct super_block * sb)
}
#include <linux/property.h>
#include <linux/kobject.h>
bool is_software_node(const struct fwnode_handle * fwnode)
int kobject_synth_uevent(struct kobject * kobj,const char * buf,size_t count)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/property.h>
#include <linux/irq.h>
void fwnode_remove_software_node(struct fwnode_handle * fwnode)
struct irq_chip no_irq_chip;
#include <linux/irq.h>
void note_interrupt(struct irq_desc * desc,irqreturn_t action_ret)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/sched/task.h>
#include <linux/printk.h>
void __put_task_struct(struct task_struct * tsk)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/kernel.h>
int get_option(char ** str,int * pint)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/sched/wake_q.h>
void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/capability.h>
bool file_ns_capable(const struct file * file,struct user_namespace * ns,int cap)
int printk_deferred(const char * fmt,...)
{
lx_emul_trace_and_stop(__func__);
}
@ -181,25 +189,9 @@ void seq_printf(struct seq_file * m,const char * f,...)
}
#include <linux/pseudo_fs.h>
struct pseudo_fs_context * init_pseudo(struct fs_context * fc,unsigned long magic)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/smp.h>
int smp_call_function_single(int cpu,void (* func)(void * info),void * info,int wait)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/uaccess.h>
unsigned long _copy_to_user(void __user * to,const void * from,unsigned long n)
int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait)
{
lx_emul_trace_and_stop(__func__);
}
@ -216,3 +208,12 @@ int string_escape_mem(const char * src,size_t isz,char * dst,size_t osz,unsigned
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/sched/wake_q.h>
void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task)
{
lx_emul_trace_and_stop(__func__);
}

View File

@ -7,6 +7,7 @@ drivers/base/devres.c
drivers/base/driver.c
drivers/base/platform.c
drivers/base/property.c
drivers/pci/pci-driver.c
kernel/async.c
kernel/irq/chip.c
kernel/irq/devres.c