Skip to content

Commit 139b4b8

Browse files
Add dtb_discovery ci-tests
1 parent 058ee70 commit 139b4b8

File tree

11 files changed

+616
-1
lines changed

11 files changed

+616
-1
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include "led-device.h"
2+
#include <cstring>
3+
#include <cstdio>
4+
#include <sstream>
5+
#include <algorithm>
6+
7+
led_device_t::led_device_t(const sim_t *sim, reg_t base, size_t size, uint32_t num_leds)
8+
: sim(sim), base_addr(base), dev_size(size),
9+
num_leds(std::min(num_leds, 32u)), led_state(0) {
10+
printf("LED device init at 0x%lx, size: 0x%lx, num_leds: %u\n",
11+
base_addr, dev_size, this->num_leds);
12+
}
13+
14+
bool led_device_t::load(reg_t addr, size_t len, uint8_t* bytes) {
15+
printf("led_device_t::load from address: 0x%lx, length: %zu\n",
16+
base_addr + addr, len);
17+
18+
if (addr == 0 && len == 4) {
19+
uint32_t masked_state = led_state & ((1u << num_leds) - 1);
20+
memcpy(bytes, &masked_state, 4);
21+
return true;
22+
}
23+
return false;
24+
}
25+
26+
bool led_device_t::store(reg_t addr, size_t len, const uint8_t* bytes) {
27+
printf("led_device_t::store to address: 0x%lx, length: %zu\n",
28+
base_addr + addr, len);
29+
30+
if (addr == 0 && len == 4) {
31+
uint32_t new_state;
32+
memcpy(&new_state, bytes, 4);
33+
led_state = new_state & ((1u << num_leds) - 1);
34+
35+
printf("LED state changed to: 0x%x\n", led_state);
36+
printf("LED pattern (%u LEDs): ", num_leds);
37+
for (int i = num_leds - 1; i >= 0; i--) {
38+
printf("%c", (led_state & (1 << i)) ? ' ' : '-');
39+
}
40+
printf(" (0x%x)\n", led_state);
41+
return true;
42+
}
43+
return false;
44+
}
45+
46+
size_t led_device_t::size() {
47+
return dev_size;
48+
}
49+
50+
led_device_t* led_parse_from_fdt(const void *fdt, const sim_t *sim,
51+
reg_t *base, std::vector<std::string> args) {
52+
if (args.size() < 3) {
53+
fprintf(stderr, "Error: led device requires 3 arguments (base, size, num_leds)\n");
54+
return nullptr;
55+
}
56+
57+
try {
58+
*base = std::stoull(args[0], nullptr, 0);
59+
reg_t size = std::stoull(args[1], nullptr, 0);
60+
uint32_t num_leds = std::stoul(args[2], nullptr, 0);
61+
62+
if (num_leds == 0 || num_leds > 32) {
63+
fprintf(stderr, "Error: num_leds must be between 1 and 32, got %u\n", num_leds);
64+
return nullptr;
65+
}
66+
67+
return new led_device_t(sim, *base, size, num_leds);
68+
} catch (const std::exception& e) {
69+
fprintf(stderr, "Error parsing LED device params: %s\n", e.what());
70+
return nullptr;
71+
}
72+
}
73+
74+
std::string led_generate_dts(const sim_t *sim, const std::vector<std::string> &args) {
75+
std::ostringstream s;
76+
reg_t base = 0x10001000;
77+
reg_t size = 0x1000;
78+
uint32_t num_leds = 8;
79+
80+
if (args.size() >= 3) {
81+
base = std::stoull(args[0], nullptr, 0);
82+
size = std::stoull(args[1], nullptr, 0);
83+
num_leds = std::stoul(args[2], nullptr, 0);
84+
}
85+
86+
s << std::hex
87+
<< " led@" << base << " {\n"
88+
<< " compatible = \"led\";\n"
89+
<< " reg = <0x0 0x" << base << " 0x0 0x" << size << ">;\n"
90+
<< std::dec
91+
<< " num-leds = <" << num_leds << ">;\n"
92+
<< std::hex
93+
<< " spike,plugin-params = \"0x" << base << ",0x" << size << "," << std::dec << num_leds << "\";\n"
94+
<< " };\n";
95+
96+
return s.str();
97+
}
98+
99+
REGISTER_DEVICE(led_device, led_parse_from_fdt, led_generate_dts)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef LED_DEVICE_H
2+
#define LED_DEVICE_H
3+
4+
#include <riscv/sim.h>
5+
#include <vector>
6+
#include <string>
7+
8+
class led_device_t : public abstract_device_t {
9+
public:
10+
led_device_t(const sim_t *sim, reg_t base, size_t size, uint32_t num_leds);
11+
12+
bool load(reg_t addr, size_t len, uint8_t* bytes) override;
13+
bool store(reg_t addr, size_t len, const uint8_t* bytes) override;
14+
size_t size() override;
15+
16+
private:
17+
const sim_t *sim;
18+
reg_t base_addr;
19+
size_t dev_size;
20+
uint32_t num_leds;
21+
uint32_t led_state;
22+
};
23+
24+
25+
26+
#endif // LED_DEVICE_H
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/dts-v1/;
2+
/ {
3+
#address-cells = <2>;
4+
#size-cells = <2>;
5+
6+
cpus {
7+
#address-cells = <1>;
8+
#size-cells = <0>;
9+
timebase-frequency = <10000000>;
10+
11+
CPU0: cpu@0 {
12+
device_type = "cpu";
13+
reg = <0>;
14+
riscv,isa = "rv64imafdc";
15+
16+
CPU0_intc: interrupt-controller {
17+
#interrupt-cells = <1>;
18+
interrupt-controller;
19+
compatible = "riscv,cpu-intc";
20+
};
21+
};
22+
};
23+
24+
memory@90000000 {
25+
device_type = "memory";
26+
reg = <0x00000000 0x90000000 0x00000000 0x10000000>;
27+
};
28+
29+
clint@2000000 {
30+
compatible = "riscv,clint0";
31+
reg = <0x0 0x2000000 0x0 0xc0000>;
32+
};
33+
34+
PLIC: plic@c000000 {
35+
compatible = "riscv,plic0";
36+
reg = <0x0 0xc000000 0x0 0x1000000>;
37+
riscv,ndev = <0x1f>;
38+
riscv,max-priority = <0xf>;
39+
#interrupt-cells = <1>;
40+
interrupt-controller;
41+
};
42+
43+
uart0: serial@10000000 {
44+
compatible = "ns16550a";
45+
reg = <0x0 0x10000000 0x0 0x100>;
46+
clock-frequency = <10000000>;
47+
interrupts = <10>;
48+
reg-shift = <0>;
49+
reg-io-width = <1>;
50+
};
51+
52+
};
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/dts-v1/;
2+
3+
/ {
4+
#address-cells = <2>;
5+
#size-cells = <2>;
6+
7+
cpus { // Container for all CPU cores
8+
#address-cells = <1>; // CPU children use 1 cell for hartid
9+
#size-cells = <0>; // CPU children don't specify size
10+
timebase-frequency = <10000000>; // Timer ticks at 10 MHz (for OS timing)
11+
12+
CPU0: cpu@0 { // First CPU core (label: CPU0, unit address: 0)
13+
device_type = "cpu"; // Identifies this as a CPU device
14+
reg = <0>; // Hartid = 0 (hardware thread ID)
15+
riscv,isa = "rv64imafdc"; // ISA: RV64 with I,M,A,F,D,C extensions
16+
};
17+
};
18+
19+
20+
memory@90000000 {
21+
device_type = "memory";
22+
reg = <0x0 0x90000000 0x0 0x00010000>;
23+
};
24+
25+
led1@10001000 {
26+
compatible = "led_device";
27+
reg = <0x0 0x10001000 0x0 0x1000>;
28+
spike,plugin-params = "16";
29+
};
30+
31+
led2@10002000 {
32+
compatible = "led_device";
33+
reg = <0x0 0x10002000 0x0 0x1000>;
34+
spike,plugin-params = "8";
35+
};
36+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/dts-v1/;
2+
3+
/ {
4+
#address-cells = <2>;
5+
#size-cells = <2>;
6+
7+
cpus { // Container for all CPU cores
8+
#address-cells = <1>; // CPU children use 1 cell for hartid
9+
#size-cells = <0>; // CPU children don't specify size
10+
timebase-frequency = <10000000>; // Timer ticks at 10 MHz (for OS timing)
11+
12+
CPU0: cpu@0 { // First CPU core (label: CPU0, unit address: 0)
13+
device_type = "cpu"; // Identifies this as a CPU device
14+
reg = <0>; // Hartid = 0 (hardware thread ID)
15+
riscv,isa = "rv64imafdc"; // ISA: RV64 with I,M,A,F,D,C extensions
16+
};
17+
};
18+
19+
20+
led@10001000 {
21+
compatible = "led_device";
22+
reg = <0x0 0x10001000 0x0 0x00001000>;
23+
spike,plugin-params = "16";
24+
};
25+
26+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/dts-v1/;
2+
/ {
3+
#address-cells = <1>;
4+
#size-cells = <1>;
5+
6+
cpus { // Container for all CPU cores
7+
#address-cells = <1>; // CPU children use 1 cell for hartid
8+
#size-cells = <0>; // CPU children don't specify size
9+
timebase-frequency = <10000000>; // Timer ticks at 10 MHz (for OS timing)
10+
11+
CPU0: cpu@0 { // First CPU core (label: CPU0, unit address: 0)
12+
device_type = "cpu"; // Identifies this as a CPU device
13+
reg = <0>; // Hartid = 0 (hardware thread ID)
14+
riscv,isa = "rv64imafdc"; // ISA: RV64 with I,M,A,F,D,C extensions
15+
};
16+
};
17+
18+
19+
memory@80000000 {
20+
device_type = "memory";
21+
reg = <0x80000000 0x10000000>; // 256MB
22+
};
23+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/dts-v1/;
2+
/ {
3+
#address-cells = <2>;
4+
#size-cells = <2>;
5+
6+
cpus { // Container for all CPU cores
7+
#address-cells = <1>; // CPU children use 1 cell for hartid
8+
#size-cells = <0>; // CPU children don't specify size
9+
timebase-frequency = <10000000>; // Timer ticks at 10 MHz (for OS timing)
10+
11+
CPU0: cpu@0 { // First CPU core (label: CPU0, unit address: 0)
12+
device_type = "cpu"; // Identifies this as a CPU device
13+
reg = <0>; // Hartid = 0 (hardware thread ID)
14+
riscv,isa = "rv64imafdc"; // ISA: RV64 with I,M,A,F,D,C extensions
15+
};
16+
};
17+
18+
19+
memory@80000000 {
20+
device_type = "memory";
21+
reg = <0x0 0x20000000 0x0 0x40000000>; // 1GB
22+
};
23+
};
24+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/dts-v1/;
2+
/ {
3+
#address-cells = <2>;
4+
#size-cells = <1>;
5+
6+
cpus { // Container for all CPU cores
7+
#address-cells = <1>; // CPU children use 1 cell for hartid
8+
#size-cells = <0>; // CPU children don't specify size
9+
timebase-frequency = <10000000>; // Timer ticks at 10 MHz (for OS timing)
10+
11+
CPU0: cpu@0 { // First CPU core (label: CPU0, unit address: 0)
12+
device_type = "cpu"; // Identifies this as a CPU device
13+
reg = <0>; // Hartid = 0 (hardware thread ID)
14+
riscv,isa = "rv64imafdc"; // ISA: RV64 with I,M,A,F,D,C extensions
15+
};
16+
};
17+
18+
19+
memory@100000000 {
20+
device_type = "memory";
21+
reg = <0x1 0x00000000 0x20000000>; // 512MB at 4GB
22+
};
23+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/dts-v1/;
2+
/ {
3+
#address-cells = <2>;
4+
#size-cells = <2>;
5+
6+
cpus { // Container for all CPU cores
7+
#address-cells = <1>; // CPU children use 1 cell for hartid
8+
#size-cells = <0>; // CPU children don't specify size
9+
timebase-frequency = <10000000>; // Timer ticks at 10 MHz (for OS timing)
10+
11+
CPU0: cpu@0 { // First CPU core (label: CPU0, unit address: 0)
12+
device_type = "cpu"; // Identifies this as a CPU device
13+
reg = <0>; // Hartid = 0 (hardware thread ID)
14+
riscv,isa = "rv64imafdc"; // ISA: RV64 with I,M,A,F,D,C extensions
15+
};
16+
};
17+
18+
19+
memory@80000000 {
20+
device_type = "memory";
21+
reg = <0x0 0x80000000 0x0 0x20000000>;
22+
};
23+
24+
memory@A0000000 {
25+
device_type = "memory";
26+
reg = <0x0 0xA0000000 0x0 0x20000000>;
27+
};
28+
};

0 commit comments

Comments
 (0)