Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial software driver for dma #100

Draft
wants to merge 43 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
92dcd32
initial software driver for dma
NazerkeT Jul 11, 2023
1da84cd
initial software stack of the dma: subject to change later, but the b…
Jul 14, 2023
20f323f
Update sdk/core/dma/dma.h
NazerkeT Jul 17, 2023
6294ef0
Update sdk/core/dma/dma.h
NazerkeT Jul 17, 2023
78f1638
updated software stack with stronger compartment support
Jul 17, 2023
ead572b
fixed some errors and added a test example
Jul 18, 2023
87f3e96
fixed some logic and cheri mistakes, third iteration
Jul 19, 2023
c565efd
add the unique pointer support to the compartment
Jul 19, 2023
e8cce57
uploading the json file for a check
Jul 26, 2023
3d11a58
fixing naming mistakes
Jul 26, 2023
d73d85d
initial software driver for dma
NazerkeT Jul 11, 2023
273cc50
initial software stack of the dma: subject to change later, but the b…
Jul 14, 2023
ee461eb
Update sdk/core/dma/dma.h
NazerkeT Jul 17, 2023
e873b18
Update sdk/core/dma/dma.h
NazerkeT Jul 17, 2023
87d8dd2
updated software stack with stronger compartment support
Jul 17, 2023
265db79
fixed some errors and added a test example
Jul 18, 2023
8313fc1
fixed some logic and cheri mistakes, third iteration
Jul 19, 2023
e2211aa
add the unique pointer support to the compartment
Jul 19, 2023
0f71c0e
uploading the json file for a check
Jul 26, 2023
05076b6
fixing naming mistakes
Jul 26, 2023
1651284
adding a dma compartment to a xmake
Jul 26, 2023
6ffc71a
adding a dma compartment to the xmake
Jul 26, 2023
6df7a1b
successfully compiled and linked version
Jul 27, 2023
7ba5106
sw after few fixes for smart pointers
Aug 2, 2023
cd5b205
software that worked with dma!
Aug 3, 2023
199a217
sw for interrupt code
Aug 4, 2023
f697ece
fixed interrupt sw errors
Aug 4, 2023
b03924c
removed redundant comments
Aug 4, 2023
759eb83
byte swap bug fixed
Aug 7, 2023
8d76a58
claims are dropped after the interrupts
Aug 7, 2023
afbb809
some multithreading model
Aug 8, 2023
0ed541c
multi-threaded threat model response v1
Aug 9, 2023
caf18a3
multithreaded execution v2
Aug 10, 2023
4848b86
combining functions to each other
Aug 10, 2023
a84a49a
formatting fixed and locks are added
Aug 11, 2023
166213d
added worker threads to the firmware
Aug 11, 2023
3f0dba7
fixed copy by reference from stack and returned to two finction api f…
Aug 11, 2023
39b5299
some debugging code
Aug 11, 2023
f4c2ffb
changes to integrate the dma to the tests and multithreaded execution
Aug 14, 2023
4d0d45e
reorganized software for working v1 and v2
Sep 3, 2023
160e2e8
sw for dma v3
Sep 4, 2023
980dca2
v4 dma sw stack - not tested yet
Sep 6, 2023
903d159
modified v4, compartment call removed
Sep 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/10.dma_test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
DMA example
===================


73 changes: 73 additions & 0 deletions examples/10.dma_test/dma_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright Microsoft and CHERIoT Contributors.
// SPDX-License-Identifier: MIT

#include <compartment.h>
#include <cstdint>
#include <cstdlib>
#include <debug.hh>
#include <utils.hh>

#include <fail-simulator-on-error.h>
#include <../../sdk/core/dma/dma.h>

#include <thread.h>
#include <thread_pool.h>

// Expose debugging features unconditionally for this compartment.
using Debug = ConditionalDebug<true, "DMA Compartment">;

using namespace thread_pool;

// Thread entry point.
void __cheri_compartment("dma_app") dma_request()
{
Debug::log("DMA app entered!");

// This is a dma process between two different memory addresses
uint32_t bytes = 1024;
uint32_t words = bytes/4;
uint32_t byteSwap = 4;

uint32_t *sourceAddress = (uint32_t*) malloc(bytes);
uint32_t *targetAddress = (uint32_t*) malloc(bytes);
uint32_t *alternateAddress = (uint32_t*) malloc(bytes);

for (int i=0; i < words; i++)
{
*(sourceAddress + i) = i + 100;
*(sourceAddress + i) = i + 200;
NazerkeT marked this conversation as resolved.
Show resolved Hide resolved
*(targetAddress + i) = 0;

}

Debug::log("Ind: 0 and last, Source values BEFORE dma: {}, {}", *(sourceAddress), *(sourceAddress + words -1 ));
Debug::log("Ind: 0 and last, Dest-n values BEFORE dma: {}, {}", *(targetAddress), *(targetAddress + words -1 ));

DMA::Device dmaDevice;
NazerkeT marked this conversation as resolved.
Show resolved Hide resolved

async([&]() {
Debug::log("Thread 1, start");

int ret = dmaDevice.configure_and_launch(sourceAddress, targetAddress, bytes, 0, 0, byteSwap);

Debug::log("Ind: 0 and last, Source values AFTER dma: {}, {}", *(sourceAddress), *(sourceAddress + words -1 ));
Debug::log("Ind: 0 and last, Dest-n values AFTER dma: {}, {}", *(targetAddress), *(targetAddress + words -1 ));

Debug::log("Thread 1, ret: {}", ret);
});

async([&]()
{
Debug::log("Thread 2, start");

int ret = dmaDevice.configure_and_launch(alternateAddress, targetAddress, bytes, 0, 0, 0);

Debug::log("Ind: 0 and last, Source values AFTER dma: {}, {}", *(alternateAddress), *(alternateAddress + words -1 ));
Debug::log("Ind: 0 and last, Dest-n values AFTER dma: {}, {}", *(targetAddress), *(targetAddress + words -1 ));

Debug::log("Thread 2, ret: {}", ret);
});

Debug::log("Ind: 0 and last, Dest-n values AFTER dma: {}, {}", *(targetAddress), *(targetAddress + words -1 ));
Debug::log("End of test");
}
39 changes: 39 additions & 0 deletions examples/10.dma_test/xmake.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
-- Copyright Microsoft and CHERIoT Contributors.
-- SPDX-License-Identifier: MIT

set_project("CHERIoT Simple DMA App")
sdkdir = "../../sdk"
includes(sdkdir)
set_toolchains("cheriot-clang")

-- Support libraries
includes(path.join(sdkdir, "lib/freestanding"),
path.join(sdkdir, "lib/atomic"),
path.join(sdkdir, "lib/crt"))

option("board")
set_default("sail")

compartment("dma")
add_files(path.join(sdkdir, "core/dma/dma_compartment.cc"))

compartment("dma_app")
add_files("dma_test.cc")

-- Firmware image for the example.
firmware("dma_test")
add_deps("crt", "freestanding", "atomic_fixed")
add_deps("dma", "dma_app")
-- add_deps("dma_app")
on_load(function(target)
target:values_set("board", "$(board)")
target:values_set("threads", {
NazerkeT marked this conversation as resolved.
Show resolved Hide resolved
{
compartment = "dma_app",
priority = 1,
entry_point = "dma_request",
stack_size = 0x400,
trusted_stack_frames = 2
}
}, {expand = false})
end)
71 changes: 71 additions & 0 deletions ibex.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"devices" :
{
"hspTimer" : {
"start" : 0x8f000800,
"length" : 0x20
},
"hspInteruptController" : {
"start" : 0x8f000600,
"length" : 0x14
},
"uart" : {
"start" : 0x8f00b000,
"length": 0x100
},
"shadow" : {
"start" : 0x200f0000,
"end" : 0x200f1800
},
"revoker" : {
"start" : 0x8f000000,
"length": 0xc
},
"dmb" : {
"start" : 0x8f0f0000,
"length": 0x400
},
"ethernet" : {
"start" : 0x98000000,
"length": 0x204
},
"LEDs" : {
"start" : 0x8f00 f004,
"end": 0x2020_0040
},
"dma" : {
"start" : 0x2020_0000,
"end" : 0x2020_0040
}
},
"instruction_memory" : {
"start" : 0x20000080,
"end" : 0x20060000
},
"heap" : {
"end" : 0x20060000
},
"revokable_memory_start" : 0x20000000,
"interrupts": [
{
"name": "Ethernet",
"number": 16,
"priority": 0
}
],
"defines" : [
"IBEX",
"IBEX_SHADOW_BASE=0x200f0000U",
"IBEX_SHADOW_SIZE=0x1800U"
],
"driver_includes" : [
"../include/",
"${sdk}/include/platform/ibex",
"${sdk}/include/platform/generic-riscv"
],
"timer_hz" : 20000000,
"tickrate_hz" : 100,
"stack_high_water_mark" : true,
"revoker" : "hardware",
"simulator" : "${board}/../scripts/deploy-ibex-fpga.sh"
}
100 changes: 100 additions & 0 deletions sdk/core/dma/dma.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include "dma_compartment.hh"
#include "futex.h"
#include "platform-dma.hh"
#include <concepts>
#include <cstddef>
#include <stdint.h>
#include <utils.hh>
#include <interrupt.h>
#include <errno.h>

DECLARE_AND_DEFINE_INTERRUPT_CAPABILITY(dmaInterruptCapability, dma, true, true);

namespace DMA
{

template<typename T>
concept IsDmaDevice = requires(T device, uint32_t *sourceAddress, uint32_t *targetAddress, size_t lengthInBytes,
uint32_t sourceStrides, uint32_t targetStrides, uint32_t byteSwapAmount)
{
{
device.write_conf_and_start(sourceAddress, targetAddress, lengthInBytes,
sourceStrides, targetStrides, byteSwapAmount)
} -> std::same_as<void>;
{
device.reset_dma()
} -> std::same_as<void>;
};

template<typename PlatformDMA>

requires IsDmaDevice<PlatformDMA>

class GenericDMA : public PlatformDMA
NazerkeT marked this conversation as resolved.
Show resolved Hide resolved
{
public:

int configure_and_launch(uint32_t *sourceAddress, uint32_t *targetAddress, uint32_t lengthInBytes,
uint32_t sourceStrides, uint32_t targetStrides, uint32_t byteSwapAmount)
{
/**
* Fetch the interrupt counter for the dma
* to use for future operations
*/

const uint32_t *dmaFutex = interrupt_futex_get(STATIC_SEALED_VALUE(dmaInterruptCapability));

/**
* Dma launch call:
* - checks for the dma ownership status,
* - for access rights,
* - creates claims for each source and destination addresses,
* - automatically resets the claims and the dma registers
* at the end of the transfer.
*/

int dmaInterruptReturn = launch_dma(sourceAddress, targetAddress, lengthInBytes,
sourceStrides, targetStrides, byteSwapAmount);

/**
* Negative interrupt return is for
* the failed dma launch and forces to wait for the interrupt.
* However, wait only until timeout elapses
*/

Timeout t{10};

while (dmaInterruptReturn < 0)
{
uint32_t realInterruptNumber = -(dmaInterruptReturn)-1;

futex_timed_wait(&t, dmaFutex, realInterruptNumber);

dmaInterruptReturn = launch_dma(sourceAddress, targetAddress, lengthInBytes,
sourceStrides, targetStrides, byteSwapAmount);

if (!t.remaining)
{
return -EINVAL;
}
}

/**
* Handle the interrupt here, once dmaFutex woke up via scheduler.
* DMA interrupt means that the dma operation is finished
* and it is time to reset and clear the dma configuration registers.
* Unlike with futex wait of other threads, as an occupying thread we
* wait indefinitely as much as needed for the dma completion
*/
futex_wait(dmaFutex, dmaInterruptReturn);

reset_and_clear_dma(dmaInterruptReturn);

return 0;
}

};

using Device = GenericDMA<PlatformDMA>;
}

Loading