Skip to content
29 changes: 9 additions & 20 deletions rust/src/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ unsafe extern "C" {
}

#[no_mangle]
pub unsafe extern "C" fn adt_check_header(_dt: *const c_void) -> c_int {
pub unsafe extern "C" fn adt_check_header() -> c_int {
unsafe {
match ADTNode::from_ptr(adt as *const ADTNode) {
Ok(_) => 0,
Expand All @@ -728,7 +728,7 @@ pub unsafe extern "C" fn adt_check_header(_dt: *const c_void) -> c_int {
}

#[no_mangle]
pub unsafe extern "C" fn adt_first_property_offset(_dt: *const c_void, offset: c_int) -> c_int {
pub unsafe extern "C" fn adt_first_property_offset(offset: c_int) -> c_int {
let ptr: *const ADTNode = unsafe { adt.add(offset as usize) as *const ADTNode };

let p: *const u8 = ADTNode::from_ptr(ptr)
Expand All @@ -743,7 +743,7 @@ pub unsafe extern "C" fn adt_first_property_offset(_dt: *const c_void, offset: c
// This function has load-bearing UB on the C side... The sound Rust equivalent
// breaks this. Recreate the UB here rather than call the new Rust function.
#[no_mangle]
pub unsafe extern "C" fn adt_next_property_offset(_dt: *const c_void, offset: c_int) -> c_int {
pub unsafe extern "C" fn adt_next_property_offset(offset: c_int) -> c_int {
let ptr: usize = unsafe { adt.add(offset as usize) as usize };
let p = ADTProperty::from_ptr(ptr).unwrap();
unsafe {
Expand All @@ -756,34 +756,33 @@ pub unsafe extern "C" fn adt_next_property_offset(_dt: *const c_void, offset: c_
}

#[no_mangle]
pub unsafe extern "C" fn adt_first_child_offset(_dt: *const c_void, offset: c_int) -> c_int {
pub unsafe extern "C" fn adt_first_child_offset(offset: c_int) -> c_int {
let ptr: *const ADTNode = unsafe { adt.add(offset as usize) as *const ADTNode };
let n = ADTNode::from_ptr(ptr).unwrap();
unsafe { n.first_child().unwrap().as_ptr().sub(adt as usize) as c_int }
}

#[no_mangle]
pub unsafe extern "C" fn adt_next_sibling_offset(_dt: *const c_void, offset: c_int) -> c_int {
pub unsafe extern "C" fn adt_next_sibling_offset(offset: c_int) -> c_int {
let ptr: *const ADTNode = unsafe { adt.add(offset as usize) as *const ADTNode };
let n = ADTNode::from_ptr(ptr).unwrap();
unsafe { n.next_sibling().unwrap().as_ptr().sub(adt as usize) as c_int }
}

#[no_mangle]
pub unsafe extern "C" fn adt_get_child_count(_dt: *const c_void, offset: c_int) -> c_int {
pub unsafe extern "C" fn adt_get_child_count(offset: c_int) -> c_int {
let ptr: *const ADTNode = unsafe { adt.add(offset as usize) as *const ADTNode };
ADTNode::from_ptr(ptr).unwrap().child_count as c_int
}

#[no_mangle]
pub unsafe extern "C" fn adt_get_property_count(_dt: *const c_void, offset: c_int) -> c_int {
pub unsafe extern "C" fn adt_get_property_count(offset: c_int) -> c_int {
let ptr: *const ADTNode = unsafe { adt.add(offset as usize) as *const ADTNode };
ADTNode::from_ptr(ptr).unwrap().property_count as c_int
}

#[no_mangle]
pub unsafe extern "C" fn adt_get_property_by_offset(
_dt: *const c_void,
offset: c_int,
) -> *const c_void {
let ptr: usize = unsafe { adt.add(offset as usize) as usize };
Expand All @@ -795,7 +794,6 @@ pub unsafe extern "C" fn adt_get_property_by_offset(

#[no_mangle]
pub unsafe extern "C" fn adt_get_property(
_dt: *const c_void,
offset: c_int,
name: *const c_char,
) -> *const c_void {
Expand All @@ -811,7 +809,6 @@ pub unsafe extern "C" fn adt_get_property(

#[no_mangle]
pub unsafe extern "C" fn adt_getprop(
_dt: *const c_void,
offset: c_int,
name: *const c_char,
lenp: *mut c_uint,
Expand All @@ -833,7 +830,6 @@ pub unsafe extern "C" fn adt_getprop(

#[no_mangle]
pub unsafe extern "C" fn adt_getprop_by_offset(
_dt: *const c_void,
offset: c_int,
namep: *mut *const c_char,
lenp: *mut c_uint,
Expand All @@ -857,7 +853,6 @@ pub unsafe extern "C" fn adt_getprop_by_offset(

#[no_mangle]
pub unsafe extern "C" fn adt_setprop(
_dt: *const c_void,
offset: c_int,
name: *const c_char,
val: *const c_void,
Expand Down Expand Up @@ -890,7 +885,6 @@ pub unsafe extern "C" fn adt_setprop(

#[no_mangle]
pub unsafe extern "C" fn adt_subnode_offset(
_dt: *const c_void,
offset: c_int,
name: *const c_char,
) -> c_int {
Expand All @@ -910,7 +904,6 @@ pub unsafe extern "C" fn adt_subnode_offset(

#[no_mangle]
pub unsafe extern "C" fn adt_is_compatible(
_dt: *const c_void,
offset: c_int,
compat: *const c_char,
) -> bool {
Expand All @@ -924,7 +917,6 @@ pub unsafe extern "C" fn adt_is_compatible(

#[no_mangle]
pub unsafe extern "C" fn adt_is_compatible_at(
_dt: *const c_void,
offset: c_int,
compat: *const c_char,
index: usize,
Expand All @@ -935,14 +927,13 @@ pub unsafe extern "C" fn adt_is_compatible_at(
}

#[no_mangle]
pub unsafe extern "C" fn adt_get_name(_dt: *const c_void, offset: c_int) -> *const c_char {
pub unsafe extern "C" fn adt_get_name(offset: c_int) -> *const c_char {
let ptr: *const ADTNode = unsafe { adt.add(offset as usize) as *const ADTNode };
ADTNode::from_ptr(ptr).unwrap().name().unwrap().as_ptr() as *const c_char
}

#[no_mangle]
pub unsafe extern "C" fn adt_getprop_copy(
_dt: *const c_void,
offset: c_int,
name: *const c_char,
out: *mut c_void,
Expand Down Expand Up @@ -975,7 +966,6 @@ pub unsafe extern "C" fn adt_getprop_copy(

#[no_mangle]
pub unsafe extern "C" fn adt_path_offset_trace(
_dt: *const c_void,
path: *const c_char,
offsets: *mut i32,
) -> c_int {
Expand Down Expand Up @@ -1007,7 +997,7 @@ pub unsafe extern "C" fn adt_path_offset_trace(
}

#[no_mangle]
pub unsafe extern "C" fn adt_path_offset(_dt: *const c_void, path: *const c_char) -> c_int {
pub unsafe extern "C" fn adt_path_offset(path: *const c_char) -> c_int {
let strpath: &str = unsafe { CStr::from_ptr(path).to_str().unwrap() };

match ADTNode::from_path(strpath) {
Expand All @@ -1018,7 +1008,6 @@ pub unsafe extern "C" fn adt_path_offset(_dt: *const c_void, path: *const c_char

#[no_mangle]
pub unsafe extern "C" fn adt_get_reg(
_dt: *const c_void,
offsets: *mut i32,
prop: *const c_char,
i: c_int,
Expand Down
68 changes: 34 additions & 34 deletions src/adt.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,61 +18,61 @@ struct adt_node_hdr {
u32 child_count;
};

#define ADT_PROP(adt, offset) ((const struct adt_property *)(((u8 *)(adt)) + (offset)))
#define ADT_PROP(offset) ((const struct adt_property *)(((u8 *)(adt)) + (offset)))

/* This API is designed to match libfdt's read-only API */

/* Required for Rust until we move xnuboot across */
u32 adt_get_size(void);

/* Basic sanity check */
int adt_check_header(const void *adt);
int adt_check_header(void);

int adt_get_property_count(const void *adt, int offset);
int adt_get_property_count(int offset);

int adt_first_property_offset(const void *adt, int offset);
int adt_first_property_offset(int offset);

int adt_next_property_offset(const void *adt, int offset);
int adt_next_property_offset(int offset);

const struct adt_property *adt_get_property_by_offset(const void *adt, int offset);
const struct adt_property *adt_get_property_by_offset(int offset);

int adt_get_child_count(const void *adt, int offset);
int adt_get_child_count(int offset);

int adt_first_child_offset(const void *adt, int offset);
int adt_next_sibling_offset(const void *adt, int offset);
int adt_first_child_offset(int offset);
int adt_next_sibling_offset(int offset);

int adt_subnode_offset(const void *adt, int parentoffset, const char *name);
int adt_path_offset(const void *adt, const char *path);
int adt_path_offset_trace(const void *adt, const char *path, int *offsets);
int adt_subnode_offset(int parentoffset, const char *name);
int adt_path_offset(const char *path);
int adt_path_offset_trace(const char *path, int *offsets);

const char *adt_get_name(const void *adt, int nodeoffset);
const struct adt_property *adt_get_property(const void *adt, int nodeoffset, const char *name);
const void *adt_getprop_by_offset(const void *adt, int offset, const char **namep, u32 *lenp);
const void *adt_getprop(const void *adt, int nodeoffset, const char *name, u32 *lenp);
int adt_setprop(void *adt, int nodeoffset, const char *name, void *value, size_t len);
int adt_getprop_copy(const void *adt, int nodeoffset, const char *name, void *out, size_t len);
const char *adt_get_name(int nodeoffset);
const struct adt_property *adt_get_property(int nodeoffset, const char *name);
const void *adt_getprop_by_offset(int offset, const char **namep, u32 *lenp);
const void *adt_getprop(int nodeoffset, const char *name, u32 *lenp);
int adt_setprop(int nodeoffset, const char *name, void *value, size_t len);
int adt_getprop_copy(int nodeoffset, const char *name, void *out, size_t len);

#define ADT_GETPROP(adt, nodeoffset, name, val) \
adt_getprop_copy(adt, nodeoffset, name, (val), sizeof(*(val)))
#define ADT_GETPROP(nodeoffset, name, val) \
adt_getprop_copy(nodeoffset, name, (val), sizeof(*(val)))

#define ADT_GETPROP_ARRAY(adt, nodeoffset, name, arr) \
adt_getprop_copy(adt, nodeoffset, name, (arr), sizeof(arr))
#define ADT_GETPROP_ARRAY(nodeoffset, name, arr) \
adt_getprop_copy(nodeoffset, name, (arr), sizeof(arr))

int adt_get_reg(const void *adt, int *path, const char *prop, int idx, u64 *addr, u64 *size);
bool adt_is_compatible(const void *adt, int nodeoffset, const char *compat);
bool adt_is_compatible_at(const void *adt, int nodeoffset, const char *compat, size_t index);
int adt_get_reg(int *path, const char *prop, int idx, u64 *addr, u64 *size);
bool adt_is_compatible(int nodeoffset, const char *compat);
bool adt_is_compatible_at(int nodeoffset, const char *compat, size_t index);

#define ADT_FOREACH_CHILD(adt, node) \
for (int _child_count = adt_get_child_count(adt, node); _child_count; _child_count = 0) \
for (node = adt_first_child_offset(adt, node); _child_count--; \
node = adt_next_sibling_offset(adt, node))
#define ADT_FOREACH_CHILD(node) \
for (int _child_count = adt_get_child_count(node); _child_count; _child_count = 0) \
for (node = adt_first_child_offset(node); _child_count--; \
node = adt_next_sibling_offset(node))

#define ADT_FOREACH_PROPERTY(adt, node, prop) \
for (int _prop_count = adt_get_property_count(adt, node), \
_poff = adt_first_property_offset(adt, node); \
#define ADT_FOREACH_PROPERTY(node, prop) \
for (int _prop_count = adt_get_property_count(node), \
_poff = adt_first_property_offset(node); \
_prop_count; _prop_count = 0) \
for (const struct adt_property *prop = ADT_PROP(adt, _poff); _prop_count--; \
prop = ADT_PROP(adt, _poff = adt_next_property_offset(adt, _poff)))
for (const struct adt_property *prop = ADT_PROP(_poff); _prop_count--; \
prop = ADT_PROP(_poff = adt_next_property_offset(_poff)))

/* Common ADT properties */
struct adt_segment_ranges {
Expand Down
6 changes: 5 additions & 1 deletion src/afk.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "malloc.h"
#include "string.h"
#include "utils.h"
#include "adt.h"

#include "dcp/parser.h"

Expand Down Expand Up @@ -510,7 +511,10 @@ int afk_epic_command(afk_epic_ep_t *epic, int channel, u16 sub_type, void *txbuf
msg.hdr.version = 2;
msg.hdr.seq = epic->seq++;
msg.sub.length = sizeof(msg.cmd);
msg.sub.version = 4;
if (adt_is_compatible(0, "J517AP"))
msg.sub.version = 3;
else
msg.sub.version = 4;
msg.sub.category = CAT_COMMAND;
msg.sub.type = sub_type;
msg.sub.seq = 0;
Expand Down
26 changes: 13 additions & 13 deletions src/aic.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ struct aic *aic;

static int aic23_init(int version, int node)
{
int ret = ADT_GETPROP(adt, node, "aic-iack-offset", &aic->regs.event);
int ret = ADT_GETPROP(node, "aic-iack-offset", &aic->regs.event);
if (ret < 0) {
printf("AIC: failed to get property aic-iack-offset\n");
return ret;
}

int32_t cap0_offset = aic->cap0_offset;
if (cap0_offset == -1) {
ret = ADT_GETPROP(adt, node, "cap0-offset", &cap0_offset);
ret = ADT_GETPROP(node, "cap0-offset", &cap0_offset);
if (ret < 0) {
printf("AIC: failed to get property cap0-offset\n");
}
Expand All @@ -65,7 +65,7 @@ static int aic23_init(int version, int node)

int32_t maxnumirq_offset = aic->maxnumirq_offset;
if (maxnumirq_offset == -1) {
ret = ADT_GETPROP(adt, node, "maxnumirq-offset", &maxnumirq_offset);
ret = ADT_GETPROP(node, "maxnumirq-offset", &maxnumirq_offset);
if (ret < 0) {
printf("AIC: failed to get property maxnumirq-offset\n");
}
Expand All @@ -90,7 +90,7 @@ static int aic23_init(int version, int node)
* AIC2, but fatal on AIC3.
*/
u32 config_base;
if (ADT_GETPROP(adt, node, "extint-baseaddress", &config_base) > 0) {
if (ADT_GETPROP(node, "extint-baseaddress", &config_base) > 0) {
aic->regs.config = config_base;
}

Expand All @@ -112,11 +112,11 @@ static int aic23_init(int version, int node)
off += sizeof(u32) * (aic->max_irq >> 5); /* HW_STATE */

/* Fill in the strides dynamically if we can */
if (ADT_GETPROP(adt, node, "extintrcfg-stride", &aic->extintrcfg_stride) < 0)
if (ADT_GETPROP(node, "extintrcfg-stride", &aic->extintrcfg_stride) < 0)
aic->extintrcfg_stride = off - start_off;
if (ADT_GETPROP(adt, node, "intmaskset-stride", &aic->intmaskset_stride) < 0)
if (ADT_GETPROP(node, "intmaskset-stride", &aic->intmaskset_stride) < 0)
aic->intmaskset_stride = off - start_off;
if (ADT_GETPROP(adt, node, "intmaskclear-stride", &aic->intmaskclear_stride) < 0)
if (ADT_GETPROP(node, "intmaskclear-stride", &aic->intmaskclear_stride) < 0)
aic->intmaskclear_stride = off - start_off;

aic->regs.reg_size = aic->regs.event + 4;
Expand All @@ -128,7 +128,7 @@ static int aic23_init(int version, int node)
aic->intmaskclear_stride);

u32 ext_intr_config_len;
const u8 *ext_intr_config = adt_getprop(adt, node, "aic-ext-intr-cfg", &ext_intr_config_len);
const u8 *ext_intr_config = adt_getprop(node, "aic-ext-intr-cfg", &ext_intr_config_len);

if (ext_intr_config) {
printf("AIC: Configuring %d external interrupts\n", ext_intr_config_len / 3);
Expand All @@ -149,25 +149,25 @@ static int aic23_init(int version, int node)
void aic_init(void)
{
int path[8];
int node = adt_path_offset_trace(adt, "/arm-io/aic", path);
int node = adt_path_offset_trace("/arm-io/aic", path);

if (node < 0) {
printf("AIC node not found!\n");
return;
}

if (adt_is_compatible(adt, node, "aic,1")) {
if (adt_is_compatible(node, "aic,1")) {
aic = &aic1;
} else if (adt_is_compatible(adt, node, "aic,2")) {
} else if (adt_is_compatible(node, "aic,2")) {
aic = &aic2;
} else if (adt_is_compatible(adt, node, "aic,3")) {
} else if (adt_is_compatible(node, "aic,3")) {
aic = &aic3;
} else {
printf("AIC: Error: Unsupported version\n");
return;
}

if (adt_get_reg(adt, path, "reg", 0, &aic->base, NULL)) {
if (adt_get_reg(path, "reg", 0, &aic->base, NULL)) {
printf("Failed to get AIC reg property!\n");
return;
}
Expand Down
Loading