mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
parent
5f5ad41ad3
commit
73d3698e2f
80
repos/os/src/drivers/platform/rpi/device_model_policy.cc
Normal file
80
repos/os/src/drivers/platform/rpi/device_model_policy.cc
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* \brief Platform driver - Device model policy for rpi
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2020-08-20
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 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.
|
||||
*/
|
||||
|
||||
#include <env.h>
|
||||
#include <rpi_device.h>
|
||||
|
||||
using Driver::Device_model;
|
||||
using Driver::Device;
|
||||
using Driver::Rpi_device;
|
||||
|
||||
void Device_model::destroy_element(Device & dev)
|
||||
{
|
||||
Rpi_device & device = static_cast<Rpi_device&>(dev);
|
||||
|
||||
{
|
||||
Irq_update_policy policy(_env.heap);
|
||||
device._irq_list.destroy_all_elements(policy);
|
||||
}
|
||||
|
||||
{
|
||||
Io_mem_update_policy policy(_env.heap);
|
||||
device._io_mem_list.destroy_all_elements(policy);
|
||||
}
|
||||
|
||||
{
|
||||
Property_update_policy policy(_env.heap);
|
||||
device._property_list.destroy_all_elements(policy);
|
||||
}
|
||||
|
||||
{
|
||||
Power_domain_update_policy policy(_env.heap);
|
||||
device._power_domain_list.destroy_all_elements(policy);
|
||||
}
|
||||
|
||||
Genode::destroy(_env.heap, &device);
|
||||
}
|
||||
|
||||
|
||||
Device & Device_model::create_element(Genode::Xml_node node)
|
||||
{
|
||||
Device::Name name = node.attribute_value("name", Device::Name());
|
||||
return *(new (_env.heap) Rpi_device(name));
|
||||
}
|
||||
|
||||
|
||||
void Device_model::update_element(Device & dev,
|
||||
Genode::Xml_node node)
|
||||
{
|
||||
Rpi_device & device = static_cast<Rpi_device&>(dev);
|
||||
|
||||
{
|
||||
Irq_update_policy policy(_env.heap);
|
||||
device._irq_list.update_from_xml(policy, node);
|
||||
}
|
||||
|
||||
{
|
||||
Io_mem_update_policy policy(_env.heap);
|
||||
device._io_mem_list.update_from_xml(policy, node);
|
||||
}
|
||||
|
||||
{
|
||||
Property_update_policy policy(_env.heap);
|
||||
device._property_list.update_from_xml(policy, node);
|
||||
}
|
||||
|
||||
{
|
||||
Power_domain_update_policy policy(_env.heap);
|
||||
device._power_domain_list.update_from_xml(policy, node);
|
||||
}
|
||||
}
|
43
repos/os/src/drivers/platform/rpi/env.h
Normal file
43
repos/os/src/drivers/platform/rpi/env.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* \brief Platform driver for rpi
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2020-08-20
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 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 _SRC__DRIVERS__PLATFORM__RPI__ENV_H_
|
||||
#define _SRC__DRIVERS__PLATFORM__RPI__ENV_H_
|
||||
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/env.h>
|
||||
#include <base/heap.h>
|
||||
|
||||
#include <device.h>
|
||||
#include <mbox.h>
|
||||
|
||||
namespace Driver {
|
||||
using namespace Genode;
|
||||
|
||||
struct Env;
|
||||
};
|
||||
|
||||
|
||||
struct Driver::Env
|
||||
{
|
||||
Genode::Env & env;
|
||||
Heap heap { env.ram(), env.rm() };
|
||||
Sliced_heap sliced_heap { env.ram(), env.rm() };
|
||||
Attached_rom_dataspace config { env, "config" };
|
||||
Device_model devices { *this };
|
||||
Mbox mbox { env };
|
||||
|
||||
Env(Genode::Env &env) : env(env) { }
|
||||
};
|
||||
|
||||
#endif /* _SRC__DRIVERS__PLATFORM__RPI__ENV_H_ */
|
63
repos/os/src/drivers/platform/rpi/framebuffer_message.h
Normal file
63
repos/os/src/drivers/platform/rpi/framebuffer_message.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* \brief Marshalling of mbox messages for framebuffer channel
|
||||
* \author Norman Feske
|
||||
* \date 2013-09-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _FRAMEBUFFER_MESSAGE_H_
|
||||
#define _FRAMEBUFFER_MESSAGE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/misc_math.h>
|
||||
#include <base/log.h>
|
||||
|
||||
/* board-specific includes */
|
||||
#include <drivers/defs/rpi.h>
|
||||
#include <platform/framebuffer_info.h>
|
||||
|
||||
namespace Platform { struct Framebuffer_message; }
|
||||
|
||||
|
||||
/**
|
||||
* Mailbox message buffer for the framebuffer channel
|
||||
*/
|
||||
struct Platform::Framebuffer_message : Framebuffer_info
|
||||
{
|
||||
Framebuffer_message(Framebuffer_info const &info) : Framebuffer_info(info) { }
|
||||
|
||||
void finalize() { }
|
||||
|
||||
static unsigned channel() { return 1; }
|
||||
|
||||
static Rpi::Videocore_cache_policy cache_policy() {
|
||||
return Rpi::COHERENT;
|
||||
}
|
||||
|
||||
void dump(char const *label)
|
||||
{
|
||||
using Genode::log;
|
||||
|
||||
log(label, " message:");
|
||||
log(" phys_width: ", phys_width);
|
||||
log(" phys_height: ", phys_height);
|
||||
log(" virt_width: ", virt_width);
|
||||
log(" virt_height: ", virt_height);
|
||||
log(" pitch: ", pitch);
|
||||
log(" depth: ", depth);
|
||||
log(" x_offset: ", x_offset);
|
||||
log(" y_offset: ", y_offset);
|
||||
log(" addr: ", Genode::Hex(addr));
|
||||
log(" size: ", Genode::Hex(size));
|
||||
}
|
||||
|
||||
inline void *operator new (__SIZE_TYPE__, void *ptr) { return ptr; }
|
||||
};
|
||||
|
||||
#endif /* _FRAMEBUFFER_MESSAGE_H_ */
|
127
repos/os/src/drivers/platform/rpi/mbox.h
Normal file
127
repos/os/src/drivers/platform/rpi/mbox.h
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* \brief Mbox for communicating between Videocore and ARM
|
||||
* \author Norman Feske
|
||||
* \date 2013-09-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _DRIVERS__PLATFORM__SPEC__RPI__MBOX_H_
|
||||
#define _DRIVERS__PLATFORM__SPEC__RPI__MBOX_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/mmio.h>
|
||||
#include <base/env.h>
|
||||
#include <os/attached_mmio.h>
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <base/log.h>
|
||||
#include <dataspace/client.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
class Mbox : Genode::Attached_mmio
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
|
||||
enum { verbose = false };
|
||||
|
||||
typedef Genode::addr_t addr_t;
|
||||
typedef Genode::uint32_t uint32_t;
|
||||
typedef Genode::Dataspace_client Dataspace_client;
|
||||
|
||||
enum { BASE = 0x2000b800,
|
||||
SIZE = 0x100 };
|
||||
|
||||
struct Read : Register<0x80, 32> { };
|
||||
|
||||
struct Status : Register<0x98, 32>
|
||||
{
|
||||
struct Rd_empty : Bitfield<30, 1> { };
|
||||
struct Wr_full : Bitfield<31, 1> { };
|
||||
};
|
||||
|
||||
struct Write : Register<0xa0, 32>
|
||||
{
|
||||
struct Channel : Bitfield<0, 4> { };
|
||||
struct Value : Bitfield<4, 26> { };
|
||||
struct Cache_policy : Bitfield<30, 2> { };
|
||||
};
|
||||
|
||||
enum { MSG_BUFFER_SIZE = 0x1000 };
|
||||
Genode::Attached_ram_dataspace _msg_buffer { _env.ram(), _env.rm(),
|
||||
MSG_BUFFER_SIZE };
|
||||
|
||||
addr_t const _msg_phys = { Dataspace_client(_msg_buffer.cap()).phys_addr() };
|
||||
|
||||
struct Delayer : Mmio::Delayer
|
||||
{
|
||||
Timer::Connection timer;
|
||||
void usleep(Genode::uint64_t us) override { timer.usleep(us); }
|
||||
|
||||
Delayer(Genode::Env &env) : timer(env) { }
|
||||
} _delayer { _env };
|
||||
|
||||
template <typename MESSAGE>
|
||||
MESSAGE &_message()
|
||||
{
|
||||
return *_msg_buffer.local_addr<MESSAGE>();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Mbox(Genode::Env &env)
|
||||
: Genode::Attached_mmio(env, BASE, SIZE), _env(env) { }
|
||||
|
||||
/**
|
||||
* Return reference to typed message buffer
|
||||
*/
|
||||
template <typename MESSAGE, typename... ARGS>
|
||||
MESSAGE &message(ARGS... args)
|
||||
{
|
||||
return *(new (_msg_buffer.local_addr<void>()) MESSAGE(args...));
|
||||
}
|
||||
|
||||
template <typename MESSAGE>
|
||||
void call()
|
||||
{
|
||||
_message<MESSAGE>().finalize();
|
||||
|
||||
if (verbose)
|
||||
_message<MESSAGE>().dump("Input");
|
||||
|
||||
/* flush pending data in the read buffer */
|
||||
while (!read<Status::Rd_empty>())
|
||||
read<Read>();
|
||||
|
||||
try { wait_for(Attempts(500), Microseconds(1), _delayer,
|
||||
Status::Wr_full::Equal(0)); }
|
||||
catch (Polling_timeout) {
|
||||
Genode::error("Mbox: timeout waiting for ready-to-write");
|
||||
return;
|
||||
}
|
||||
|
||||
Write::access_t value = 0;
|
||||
Write::Channel:: set(value, MESSAGE::channel());
|
||||
Write::Value:: set(value, _msg_phys >> Write::Value::SHIFT);
|
||||
Write::Cache_policy::set(value, MESSAGE::cache_policy());
|
||||
write<Write>(value);
|
||||
|
||||
try { wait_for(Attempts(500), Microseconds(1), _delayer,
|
||||
Status::Rd_empty::Equal(0)); }
|
||||
catch (Polling_timeout) {
|
||||
Genode::error("Mbox: timeout waiting for response");
|
||||
return;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
_message<MESSAGE>().dump("Output");
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _DRIVERS__PLATFORM__SPEC__RPI__MBOX_H_ */
|
133
repos/os/src/drivers/platform/rpi/property_command.h
Normal file
133
repos/os/src/drivers/platform/rpi/property_command.h
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* \brief Command definitions for the property mbox channel
|
||||
* \author Norman Feske
|
||||
* \date 2013-09-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _PROPERTY_COMMAND_H_
|
||||
#define _PROPERTY_COMMAND_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
|
||||
namespace Property_command {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
struct Get_power_state
|
||||
{
|
||||
static uint32_t opcode() { return 0x00020001; };
|
||||
|
||||
struct Request
|
||||
{
|
||||
uint32_t const device_id;
|
||||
|
||||
Request(uint32_t device_id) : device_id(device_id) { }
|
||||
};
|
||||
|
||||
struct Response
|
||||
{
|
||||
uint32_t const device_id = 0;
|
||||
uint32_t const state = 0;
|
||||
};
|
||||
};
|
||||
|
||||
struct Set_power_state
|
||||
{
|
||||
static uint32_t opcode() { return 0x00028001; };
|
||||
|
||||
struct Request
|
||||
{
|
||||
uint32_t const device_id;
|
||||
uint32_t const state;
|
||||
|
||||
Request(uint32_t device_id, bool enable, bool wait)
|
||||
:
|
||||
device_id(device_id),
|
||||
state(enable | (wait << 1))
|
||||
{ }
|
||||
};
|
||||
|
||||
struct Response
|
||||
{
|
||||
uint32_t const device_id = 0;
|
||||
uint32_t const state = 0;
|
||||
};
|
||||
};
|
||||
|
||||
struct Get_clock_rate
|
||||
{
|
||||
static uint32_t opcode() { return 0x00030002; };
|
||||
|
||||
struct Request
|
||||
{
|
||||
uint32_t const clock_id;
|
||||
|
||||
Request(uint32_t clock_id) : clock_id(clock_id) { }
|
||||
};
|
||||
|
||||
struct Response
|
||||
{
|
||||
uint32_t const clock_id = 0;
|
||||
uint32_t const hz = 0;
|
||||
};
|
||||
};
|
||||
|
||||
struct Allocate_buffer
|
||||
{
|
||||
static uint32_t opcode() { return 0x00040001; };
|
||||
|
||||
struct Request
|
||||
{
|
||||
uint32_t const alignment = 0x100;
|
||||
};
|
||||
|
||||
struct Response
|
||||
{
|
||||
uint32_t const address = 0;
|
||||
uint32_t const size = 0;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct Release_buffer
|
||||
{
|
||||
static uint32_t opcode() { return 0x00048001; };
|
||||
};
|
||||
|
||||
|
||||
struct Get_physical_w_h
|
||||
{
|
||||
static uint32_t opcode() { return 0x00040003; };
|
||||
|
||||
struct Response
|
||||
{
|
||||
uint32_t const width = 0;
|
||||
uint32_t const height = 0;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct Set_physical_w_h
|
||||
{
|
||||
static uint32_t opcode() { return 0x00048003; };
|
||||
|
||||
struct Request
|
||||
{
|
||||
uint32_t const width;
|
||||
uint32_t const height;
|
||||
|
||||
Request(uint32_t width, uint32_t height)
|
||||
: width(width), height(height) { }
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _PROPERTY_COMMAND_H_ */
|
225
repos/os/src/drivers/platform/rpi/property_message.h
Normal file
225
repos/os/src/drivers/platform/rpi/property_message.h
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* \brief Marshalling of mbox messages for property channel
|
||||
* \author Norman Feske
|
||||
* \date 2013-09-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__DRIVERS__PLATFORM__RPI__PROPERTY_MESSAGE_H_
|
||||
#define _SRC__DRIVERS__PLATFORM__RPI__PROPERTY_MESSAGE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/misc_math.h>
|
||||
#include <base/log.h>
|
||||
|
||||
/* board-specific includes */
|
||||
#include <drivers/defs/rpi.h>
|
||||
|
||||
namespace Driver {
|
||||
using namespace Genode;
|
||||
struct Property_message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mailbox message buffer for the property channel
|
||||
*
|
||||
* This data structure is overlayed with memory shared with the VC. It
|
||||
* contains a header, followed by a sequence of so-called command tags, wrapped
|
||||
* up by a zero as an end marker.
|
||||
*/
|
||||
struct Driver::Property_message
|
||||
{
|
||||
uint32_t buf_size = 0;
|
||||
|
||||
enum Code { REQUEST = 0,
|
||||
RESPONSE_SUCCESS = 0x80000000 };
|
||||
|
||||
Code code = REQUEST;
|
||||
|
||||
/*
|
||||
* Start of the buffer that contains a sequence of tags
|
||||
*/
|
||||
char buffer[0];
|
||||
|
||||
/*
|
||||
* There must be no member variables after this point
|
||||
*/
|
||||
|
||||
/*
|
||||
* Each tag consists of a header, a part with request arguments, and a
|
||||
* part with responses.
|
||||
*/
|
||||
template <typename TAG>
|
||||
struct Tag
|
||||
{
|
||||
uint32_t const opcode;
|
||||
|
||||
/**
|
||||
* Size of tag buffer
|
||||
*/
|
||||
uint32_t const buf_size;
|
||||
|
||||
/**
|
||||
* Size of request part of the tag
|
||||
*
|
||||
* The value is never changed locally. Therefore, it is declared as
|
||||
* const. However, it will be updated by the VC. So we declare it
|
||||
* volatile, too.
|
||||
*/
|
||||
uint32_t volatile const len;
|
||||
|
||||
char payload[0];
|
||||
|
||||
/**
|
||||
* Utility for returning a response size of a tag type
|
||||
*
|
||||
* Depending on the presence of a 'TAG::Response' type, we need to
|
||||
* return the actual size of the response (if the type is present) or
|
||||
* 0. Both overloads are called with a compliant parameter 0. But only
|
||||
* if 'T::Response' exists, the first overload is selected.
|
||||
*
|
||||
* SFINAE to the rescue!
|
||||
*/
|
||||
template <typename T>
|
||||
static size_t response_size(typename T::Response *)
|
||||
{
|
||||
return sizeof(typename T::Response);
|
||||
}
|
||||
|
||||
template <typename>
|
||||
static size_t response_size(...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static size_t request_size(typename T::Request *)
|
||||
{
|
||||
return sizeof(typename T::Request);
|
||||
}
|
||||
|
||||
template <typename>
|
||||
static size_t request_size(...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct Placeable : T
|
||||
{
|
||||
template <typename... ARGS>
|
||||
Placeable(ARGS... args) : T(args...) { }
|
||||
|
||||
inline void *operator new (__SIZE_TYPE__, void *ptr) { return ptr; }
|
||||
};
|
||||
|
||||
template <typename T, typename... ARGS>
|
||||
void construct_request(typename T::Request *, ARGS... args)
|
||||
{
|
||||
new ((typename T::Request *)payload)
|
||||
Placeable<typename T::Request>(args...);
|
||||
}
|
||||
|
||||
template <typename>
|
||||
void construct_request(...) { }
|
||||
|
||||
template <typename T>
|
||||
void construct_response(typename T::Response *)
|
||||
{
|
||||
new (payload) Placeable<typename T::Response>;
|
||||
}
|
||||
|
||||
template <typename>
|
||||
void construct_response(...) { }
|
||||
|
||||
static constexpr size_t payload_size()
|
||||
{
|
||||
return max(request_size<TAG>(0), response_size<TAG>(0));
|
||||
}
|
||||
|
||||
template <typename... REQUEST_ARGS>
|
||||
Tag(REQUEST_ARGS... request_args)
|
||||
:
|
||||
opcode(TAG::opcode()),
|
||||
buf_size(payload_size()),
|
||||
len(request_size<TAG>(0))
|
||||
{
|
||||
/*
|
||||
* The order is important. If we called 'construct_response' after
|
||||
* 'construct_request', we would overwrite the request parameters
|
||||
* with the default response.
|
||||
*/
|
||||
construct_response<TAG>(0);
|
||||
construct_request<TAG>(0, request_args...);
|
||||
}
|
||||
|
||||
inline void *operator new (__SIZE_TYPE__, void *ptr) { return ptr; }
|
||||
};
|
||||
|
||||
void reset()
|
||||
{
|
||||
buf_size = 0;
|
||||
code = REQUEST;
|
||||
}
|
||||
|
||||
/**
|
||||
* \return reference to tag in the message buffer
|
||||
*/
|
||||
template <typename POLICY, typename... REQUEST_ARGS>
|
||||
typename POLICY::Response const &append(REQUEST_ARGS... request_args)
|
||||
{
|
||||
auto *tag = new (buffer + buf_size) Tag<POLICY>(request_args...);
|
||||
|
||||
buf_size += sizeof(Tag<POLICY>) + Tag<POLICY>::payload_size();
|
||||
|
||||
return *(typename POLICY::Response *)tag->payload;
|
||||
}
|
||||
|
||||
template <typename POLICY, typename... REQUEST_ARGS>
|
||||
void append_no_response(REQUEST_ARGS... request_args)
|
||||
{
|
||||
new (buffer + buf_size) Tag<POLICY>(request_args...);
|
||||
|
||||
buf_size += sizeof(Tag<POLICY>) + Tag<POLICY>::payload_size();
|
||||
}
|
||||
|
||||
void finalize()
|
||||
{
|
||||
/* append end tag */
|
||||
*(uint32_t *)(buffer + buf_size) = 0;
|
||||
buf_size += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
static unsigned channel() { return 8; }
|
||||
|
||||
static Rpi::Videocore_cache_policy cache_policy()
|
||||
{
|
||||
return Rpi::NON_COHERENT; /* for channel 8 only */
|
||||
}
|
||||
|
||||
void dump(char const *label)
|
||||
{
|
||||
unsigned const *buf = (unsigned *)this;
|
||||
log(label, " message:");
|
||||
for (unsigned i = 0;; i++) {
|
||||
for (unsigned j = 0; j < 8; j++) {
|
||||
unsigned const msg_word_idx = i*8 + j;
|
||||
log(" ", Hex(buf[msg_word_idx]));
|
||||
if (msg_word_idx*sizeof(unsigned) < buf_size)
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void *operator new (__SIZE_TYPE__, void *ptr) { return ptr; }
|
||||
};
|
||||
|
||||
#endif /* _SRC__DRIVERS__PLATFORM__RPI__PROPERTY_MESSAGE_H_ */
|
83
repos/os/src/drivers/platform/rpi/rpi_device.cc
Normal file
83
repos/os/src/drivers/platform/rpi/rpi_device.cc
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* \brief Platform driver - Device abstraction for rpi
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2020-08-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 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.
|
||||
*/
|
||||
|
||||
#include <property_command.h>
|
||||
#include <property_message.h>
|
||||
#include <rpi_device.h>
|
||||
#include <session_component.h>
|
||||
|
||||
|
||||
unsigned Driver::Rpi_device::Power_domain::id()
|
||||
{
|
||||
if (name == "sdhci") { return 0; }
|
||||
if (name == "uart_0") { return 1; }
|
||||
if (name == "uart_1") { return 2; }
|
||||
if (name == "usb") { return 3; }
|
||||
if (name == "i2c_0") { return 4; }
|
||||
if (name == "i2c_1") { return 5; }
|
||||
if (name == "i2c_2") { return 6; }
|
||||
if (name == "spi") { return 7; }
|
||||
if (name == "ccp2tx") { return 8; }
|
||||
|
||||
warning("Invalid power-domain ", name);
|
||||
return ~0U;
|
||||
};
|
||||
|
||||
|
||||
bool Driver::Rpi_device::acquire(Driver::Session_component & sc)
|
||||
{
|
||||
bool ret = Driver::Device::acquire(sc);
|
||||
|
||||
if (ret) {
|
||||
_power_domain_list.for_each([&] (Power_domain & p) {
|
||||
auto & msg = sc.env().mbox.message<Property_message>();
|
||||
msg.append_no_response<Property_command::Set_power_state>(p.id(),
|
||||
true,
|
||||
true);
|
||||
sc.env().mbox.call<Property_message>();
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void Driver::Rpi_device::release(Session_component & sc)
|
||||
{
|
||||
_power_domain_list.for_each([&] (Power_domain & p) {
|
||||
auto & msg = sc.env().mbox.message<Property_message>();
|
||||
msg.append_no_response<Property_command::Set_power_state>(p.id(),
|
||||
true,
|
||||
true);
|
||||
sc.env().mbox.call<Property_message>();
|
||||
});
|
||||
|
||||
return Driver::Device::release(sc);
|
||||
}
|
||||
|
||||
|
||||
void Driver::Rpi_device::_report_platform_specifics(Genode::Xml_generator & /*xml*/,
|
||||
Driver::Session_component & /*sc*/)
|
||||
{
|
||||
//_clock_list.for_each([&] (Clock & c) {
|
||||
// Avl_string_base * asb =
|
||||
// sc.env().ccm.tree.first()->find_by_name(c.name.string());
|
||||
// if (!asb || !c.driver_name.valid()) { return; }
|
||||
// Driver::Clock & clock =
|
||||
// static_cast<Driver::Clock::Clock_tree_element*>(asb)->object();
|
||||
// xml.node("clock", [&] () {
|
||||
// xml.attribute("rate", clock.get_rate());
|
||||
// xml.attribute("name", c.driver_name);
|
||||
// });
|
||||
//});
|
||||
}
|
89
repos/os/src/drivers/platform/rpi/rpi_device.h
Normal file
89
repos/os/src/drivers/platform/rpi/rpi_device.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* \brief Platform driver - Device abstraction for rpi
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2020-08-20
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 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 _SRC__DRIVERS__PLATFORM__IMX8MQ__RPI_DEVICE_H_
|
||||
#define _SRC__DRIVERS__PLATFORM__IMX8MQ__RPI_DEVICE_H_
|
||||
|
||||
#include <device.h>
|
||||
|
||||
namespace Driver {
|
||||
using namespace Genode;
|
||||
|
||||
class Rpi_device;
|
||||
struct Power_domain_update_policy;
|
||||
}
|
||||
|
||||
|
||||
class Driver::Rpi_device : public Driver::Device
|
||||
{
|
||||
public:
|
||||
|
||||
struct Power_domain : List_model<Power_domain>::Element
|
||||
{
|
||||
using Name = Genode::String<64>;
|
||||
|
||||
Name name;
|
||||
|
||||
Power_domain(Name name) : name(name) {}
|
||||
|
||||
unsigned id();
|
||||
};
|
||||
|
||||
bool acquire(Session_component &) override;
|
||||
void release(Session_component &) override;
|
||||
|
||||
Rpi_device(Device::Name name) : Device(name) {}
|
||||
|
||||
protected:
|
||||
|
||||
friend class Driver::Device_model;
|
||||
friend class List_model<Device>;
|
||||
|
||||
void _report_platform_specifics(Xml_generator &,
|
||||
Session_component &) override;
|
||||
|
||||
List_model<Power_domain> _power_domain_list {};
|
||||
};
|
||||
|
||||
|
||||
struct Driver::Power_domain_update_policy
|
||||
: Genode::List_model<Rpi_device::Power_domain>::Update_policy
|
||||
{
|
||||
Genode::Allocator & alloc;
|
||||
|
||||
Power_domain_update_policy(Genode::Allocator & alloc) : alloc(alloc) {}
|
||||
|
||||
void destroy_element(Element & pd) {
|
||||
Genode::destroy(alloc, &pd); }
|
||||
|
||||
Element & create_element(Genode::Xml_node node)
|
||||
{
|
||||
Element::Name name = node.attribute_value("name", Element::Name());
|
||||
return *(new (alloc) Element(name));
|
||||
}
|
||||
|
||||
void update_element(Element &, Genode::Xml_node) {}
|
||||
|
||||
static bool element_matches_xml_node(Element const & pd, Genode::Xml_node node)
|
||||
{
|
||||
Element::Name name = node.attribute_value("name", Element::Name());
|
||||
return name == pd.name;
|
||||
}
|
||||
|
||||
static bool node_is_element(Genode::Xml_node node)
|
||||
{
|
||||
return node.has_type("power-domain");
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _SRC__DRIVERS__PLATFORM__IMX8MQ__RPI_DEVICE_H_ */
|
14
repos/os/src/drivers/platform/rpi/target.mk
Normal file
14
repos/os/src/drivers/platform/rpi/target.mk
Normal file
@ -0,0 +1,14 @@
|
||||
TARGET = rpi_new_platform_drv
|
||||
REQUIRES = arm_v6
|
||||
SRC_CC = device.cc
|
||||
SRC_CC += device_component.cc
|
||||
SRC_CC += device_model_policy.cc
|
||||
SRC_CC += rpi_device.cc
|
||||
SRC_CC += main.cc
|
||||
SRC_CC += session_component.cc
|
||||
SRC_CC += root.cc
|
||||
INC_DIR = $(PRG_DIR) $(REP_DIR)/src/drivers/platform/spec/arm
|
||||
LIBS = base
|
||||
|
||||
vpath %.cc $(PRG_DIR)
|
||||
vpath %.cc $(REP_DIR)/src/drivers/platform/spec/arm
|
Loading…
Reference in New Issue
Block a user