mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
hw: provide processor broadcasts in core
A processor broadcast executes a function on all available processors which is needed at least to do MMU cache-flushes globally. ref #1076
This commit is contained in:
parent
395e955756
commit
56e4588e91
207
base-hw/src/core/include/processor_broadcast.h
Normal file
207
base-hw/src/core/include/processor_broadcast.h
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* \brief Utility to execute a function on all available processors
|
||||||
|
* \author Martin Stein
|
||||||
|
* \date 2014-03-07
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROCESSOR_BROADCAST_H_
|
||||||
|
#define _PROCESSOR_BROADCAST_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/thread.h>
|
||||||
|
#include <base/signal.h>
|
||||||
|
|
||||||
|
namespace Genode {
|
||||||
|
|
||||||
|
enum { PROCESSOR_BROADCAST_RECEIVER_STACK_SIZE = 4 * 1024 };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functionality that can be broadcasted on all available processors
|
||||||
|
*/
|
||||||
|
class Processor_broadcast_operation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for the signalling between broadcast and receiver
|
||||||
|
*/
|
||||||
|
class Processor_broadcast_signal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processor local receiver of broadcasted functions
|
||||||
|
*/
|
||||||
|
class Processor_broadcast_receiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a function on all available processors
|
||||||
|
*/
|
||||||
|
class Processor_broadcast;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return broadcast singleton
|
||||||
|
*/
|
||||||
|
Processor_broadcast * processor_broadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
class Genode::Processor_broadcast_operation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef void (*Entry)(void * const);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Entry const _entry;
|
||||||
|
void * const _data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* \param entry entry to the operation code
|
||||||
|
* \param data pointer to operation specific input/output data
|
||||||
|
*/
|
||||||
|
Processor_broadcast_operation(Entry const entry, void * const data)
|
||||||
|
:
|
||||||
|
_entry(entry), _data(data)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute operation processor-locally
|
||||||
|
*/
|
||||||
|
void execute() const { _entry(_data); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Genode::Processor_broadcast_signal
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Signal_context _context;
|
||||||
|
Signal_receiver _receiver;
|
||||||
|
Signal_transmitter _transmitter;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
Processor_broadcast_signal()
|
||||||
|
:
|
||||||
|
_transmitter(_receiver.manage(&_context))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submit the signal
|
||||||
|
*/
|
||||||
|
void submit() { _transmitter.submit(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for signal submission
|
||||||
|
*/
|
||||||
|
void await() { _receiver.wait_for_signal(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Genode::Processor_broadcast_receiver
|
||||||
|
:
|
||||||
|
public Thread<PROCESSOR_BROADCAST_RECEIVER_STACK_SIZE>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
typedef Processor_broadcast_operation Operation;
|
||||||
|
typedef Processor_broadcast_signal Signal;
|
||||||
|
|
||||||
|
Operation const * _operation;
|
||||||
|
Signal _start;
|
||||||
|
Signal _end;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
Processor_broadcast_receiver() : Thread("processor_broadcast") { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start receiver on a specific processor
|
||||||
|
*
|
||||||
|
* \param processor_id kernel name of targeted processor
|
||||||
|
*/
|
||||||
|
void init(unsigned const processor_id)
|
||||||
|
{
|
||||||
|
Thread::utcb()->core_start_info()->init(processor_id);
|
||||||
|
Thread::start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start remote execution of an operation
|
||||||
|
*
|
||||||
|
* \param operation desired operation
|
||||||
|
*/
|
||||||
|
void start_executing(Operation const * const operation)
|
||||||
|
{
|
||||||
|
_operation = operation;
|
||||||
|
_start.submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait until the remote execution of the current operation is done
|
||||||
|
*/
|
||||||
|
void end_executing() { _end.await(); }
|
||||||
|
|
||||||
|
|
||||||
|
/*****************
|
||||||
|
** Thread_base **
|
||||||
|
*****************/
|
||||||
|
|
||||||
|
void entry()
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
_start.await();
|
||||||
|
_operation->execute();
|
||||||
|
_end.submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Genode::Processor_broadcast
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
typedef Processor_broadcast_operation Operation;
|
||||||
|
typedef Processor_broadcast_receiver Receiver;
|
||||||
|
|
||||||
|
Receiver _receiver[PROCESSORS];
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
Processor_broadcast()
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < PROCESSORS; i++) { _receiver[i].init(i); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute operation on all available processors
|
||||||
|
*
|
||||||
|
* \param operation desired operation
|
||||||
|
*/
|
||||||
|
void execute(Operation const * const operation)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < PROCESSORS; i++) {
|
||||||
|
_receiver[i].start_executing(operation);
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < PROCESSORS; i++) {
|
||||||
|
_receiver[i].end_executing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _PROCESSOR_BROADCAST_H_ */
|
24
base-hw/src/core/processor_broadcast.cc
Normal file
24
base-hw/src/core/processor_broadcast.cc
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* \brief Utility to execute a function on all available processors
|
||||||
|
* \author Martin Stein
|
||||||
|
* \date 2014-03-07
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* core includes */
|
||||||
|
#include <processor_broadcast.h>
|
||||||
|
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
|
Processor_broadcast * Genode::processor_broadcast()
|
||||||
|
{
|
||||||
|
static Processor_broadcast s;
|
||||||
|
return &s;
|
||||||
|
}
|
@ -54,6 +54,7 @@ SRC_CC += console.cc \
|
|||||||
kernel/irq.cc \
|
kernel/irq.cc \
|
||||||
kernel/scheduler.cc \
|
kernel/scheduler.cc \
|
||||||
kernel/processor.cc \
|
kernel/processor.cc \
|
||||||
|
processor_broadcast.cc \
|
||||||
rm_session_support.cc \
|
rm_session_support.cc \
|
||||||
trustzone.cc \
|
trustzone.cc \
|
||||||
pager.cc \
|
pager.cc \
|
||||||
|
Loading…
Reference in New Issue
Block a user