1#![cfg_attr(not(feature = "std"), no_std)]
8extern crate core;
9
10use crate::memory::MemoryMapper;
11
12mod macros;
13
14pub mod fpgamgrregs;
15pub mod l3regs;
16pub mod memory;
17pub mod rstmgr;
18pub mod sdr;
19pub mod sysmgr;
20
21macro_rules! declare_field {
22 ($(#[$field_attr:meta])* $field_name: ident, $const_name: ident, $ty: ty [pointer]) => {
23 paste::paste! {
24 $(#[$field_attr])*
25 pub unsafe fn [< $field_name _ptr >](&self) -> *const $ty {
26 self.memory.as_ptr::<u8>().add(offsets::$const_name) as *const $ty
27 }
28
29 $(#[$field_attr])*
30 pub unsafe fn [< $field_name _ptr_mut >](&mut self) -> *mut $ty {
31 self.memory.as_mut_ptr::<u8>().add(offsets::$const_name) as *mut $ty
32 }
33
34 $(#[$field_attr])*
35 pub fn $field_name(&self) -> &$ty {
36 unsafe {
37 &*(self.memory.as_ptr::<u8>().add(offsets::$const_name) as *const $ty)
38 }
39 }
40
41 $(#[$field_attr])*
42 pub fn [< $field_name _mut >](&mut self) -> &$ty {
43 unsafe {
44 &mut *(self.memory.as_mut_ptr::<u8>().add(offsets::$const_name) as *mut $ty)
45 }
46 }
47 }
48 };
49 ($(#[$field_attr:meta])* $field_name: ident, $const_name: ident, $ty: ty []) => {
50 paste::paste! {
51 $(#[$field_attr])*
52 pub fn $field_name(&self) -> &$ty {
53 unsafe {
54 &*((self.memory.as_ptr::<u8>().add(offsets::$const_name)) as *const $ty)
55 }
56 }
57
58 $(#[$field_attr])*
59 pub fn [< $field_name _mut >](&mut self) -> &mut $ty {
60 unsafe {
61 &mut *((self.memory.as_mut_ptr::<u8>().add(offsets::$const_name)) as *mut $ty)
62 }
63 }
64 }
65 };
66}
67
68macro_rules! create_memory_locations {
70 ($(
71 $(#[$field_attr:meta])*
72 $field_name: ident ($const_name: ident): $ty: ty $([$($tags: ident)*])? => $start: literal .. $end: literal
73 );* $(;)?) => {
74 #[allow(dead_code)]
76 mod addresses {
77 $(
78 pub const $const_name: usize = $start;
79 )*
80 }
81
82 #[allow(dead_code)]
84 mod offsets {
85 $(
86 pub const $const_name: usize = (($start as usize) .saturating_sub(crate::addresses::BASE));
87 )*
88 }
89
90 #[allow(dead_code)]
92 mod sizes {
93 $(
94 pub const $const_name: usize = ($end - $start);
95 )*
96 }
97
98 pub mod ranges {
100 $(
101 pub const $const_name: core::ops::Range<usize> = $start .. $end;
102 )*
103 }
104
105 #[derive(Debug, Copy, Clone)]
106 pub struct SocFpga<M: memory::MemoryMapper> {
107 pub memory: M,
108 }
109
110 impl<M: memory::MemoryMapper> SocFpga<M> {
111 pub fn new(memory: M) -> Self {
112 Self { memory }
113 }
114
115 $(
116 declare_field!($(#[$field_attr])* $field_name, $const_name, $ty [$($($tags)*)?]);
117 )*
118 }
119 };
120}
121
122create_memory_locations! {
123 base(BASE): u8 [pointer] => 0xFF000000 .. 0xFFFFFFFF;
125
126 host_memory(HOST_MEMORY): u8 [pointer] => 0x20000000 .. 0x3FFFFFFF;
128
129 regs(FPGAMGRREGS): fpgamgrregs::FpgaManagerRegs => 0xFF706000 .. 0xFF706FFF;
131
132 data(FPGAMGRDATA): u8 [pointer] => 0xFFB90000 .. 0xFFB90003;
134
135 sdr(SDR): sdr::SdramCtrl => 0xFFC20000 .. 0xFFC2FFFF;
137
138 rstmgr(RSTMGR): rstmgr::ResetManager => 0xFFD05000 .. 0xFFD050FF;
140
141 l3regs(L3_REGS): l3regs::L3Regs => 0xFF800000 .. 0xFF87FFFF;
143
144 sysmgr(SYSMGR): sysmgr::SystemManagerModule => 0xFFD08000 .. 0xFFD08FFF;
146}
147
148#[cfg(feature = "std")]
149impl Default for SocFpga<memory::DevMemMemoryMapper> {
150 fn default() -> Self {
151 let memory = memory::DevMemMemoryMapper::create(addresses::BASE, sizes::BASE)
152 .expect("Could not create memory mapper");
153
154 Self::new(memory)
155 }
156}
157
158#[cfg(feature = "std")]
159impl SocFpga<memory::BufferMemoryMapper> {
160 pub fn create_for_test() -> Self {
161 let memory = memory::BufferMemoryMapper::new(sizes::BASE);
162
163 Self::new(memory)
164 }
165}