📄 device.c
字号:
const char *property, int boolean){ signed32 new_boolean = (boolean ? -1 : 0); device_add_property(me, property, boolean_property, &new_boolean, sizeof(new_boolean), &new_boolean, sizeof(new_boolean), NULL, permenant_object);}INLINE_DEVICE\(int)device_find_boolean_property(device *me, const char *property){ const device_property *node; unsigned_cell boolean; node = device_find_property(me, property); if (node == (device_property*)0 || node->type != boolean_property) device_error(me, "property %s not found or of wrong type", property); ASSERT(sizeof(boolean) == node->sizeof_array); memcpy(&boolean, node->array, sizeof(boolean)); return boolean;}INLINE_DEVICE\(void)device_add_ihandle_runtime_property(device *me, const char *property, const ihandle_runtime_property_spec *ihandle){ /* enter the full path as the init array */ device_add_property(me, property, ihandle_property, ihandle->full_path, strlen(ihandle->full_path) + 1, NULL, 0, NULL, permenant_object);}INLINE_DEVICE\(void)device_find_ihandle_runtime_property(device *me, const char *property, ihandle_runtime_property_spec *ihandle){ device_property_entry *entry = find_property_entry(me, property); TRACE(trace_devices, ("device_find_ihandle_runtime_property(me=0x%lx, property=%s)\n", (long)me, property)); if (entry == NULL || entry->value->type != ihandle_property || entry->value->disposition != permenant_object) device_error(me, "property %s not found or of wrong type", property); ASSERT(entry->init_array != NULL); /* the full path */ ihandle->full_path = entry->init_array;}INLINE_DEVICE\(void)device_set_ihandle_property(device *me, const char *property, device_instance *ihandle){ unsigned_cell cells; cells = H2BE_cell(device_instance_to_external(ihandle)); device_set_property(me, property, ihandle_property, &cells, sizeof(cells)); }INLINE_DEVICE\(device_instance *)device_find_ihandle_property(device *me, const char *property){ const device_property *node; unsigned_cell ihandle; device_instance *instance; node = device_find_property(me, property); if (node == NULL || node->type != ihandle_property) device_error(me, "property %s not found or of wrong type", property); if (node->array == NULL) device_error(me, "runtime property %s not yet initialized", property); ASSERT(sizeof(ihandle) == node->sizeof_array); memcpy(&ihandle, node->array, sizeof(ihandle)); instance = external_to_device_instance(me, BE2H_cell(ihandle)); ASSERT(instance != NULL); return instance;}INLINE_DEVICE\(void)device_add_integer_property(device *me, const char *property, signed_cell integer){ H2BE(integer); device_add_property(me, property, integer_property, &integer, sizeof(integer), &integer, sizeof(integer), NULL, permenant_object);}INLINE_DEVICE\(signed_cell)device_find_integer_property(device *me, const char *property){ const device_property *node; signed_cell integer; TRACE(trace_devices, ("device_find_integer(me=0x%lx, property=%s)\n", (long)me, property)); node = device_find_property(me, property); if (node == (device_property*)0 || node->type != integer_property) device_error(me, "property %s not found or of wrong type", property); ASSERT(sizeof(integer) == node->sizeof_array); memcpy(&integer, node->array, sizeof(integer)); return BE2H_cell(integer);}INLINE_DEVICE\(int)device_find_integer_array_property(device *me, const char *property, unsigned index, signed_cell *integer){ const device_property *node; int sizeof_integer = sizeof(*integer); signed_cell *cell; TRACE(trace_devices, ("device_find_integer(me=0x%lx, property=%s)\n", (long)me, property)); /* check things sane */ node = device_find_property(me, property); if (node == (device_property*)0 || (node->type != integer_property && node->type != array_property)) device_error(me, "property %s not found or of wrong type", property); if ((node->sizeof_array % sizeof_integer) != 0) device_error(me, "property %s contains an incomplete number of cells", property); if (node->sizeof_array <= sizeof_integer * index) return 0; /* Find and convert the value */ cell = ((signed_cell*)node->array) + index; *integer = BE2H_cell(*cell); return node->sizeof_array / sizeof_integer;}STATIC_INLINE_DEVICE\(unsigned_cell *)unit_address_to_cells(const device_unit *unit, unsigned_cell *cell, int nr_cells){ int i; ASSERT(nr_cells == unit->nr_cells); for (i = 0; i < unit->nr_cells; i++) { *cell = H2BE_cell(unit->cells[i]); cell += 1; } return cell;}STATIC_INLINE_DEVICE\(const unsigned_cell *)cells_to_unit_address(const unsigned_cell *cell, device_unit *unit, int nr_cells){ int i; memset(unit, 0, sizeof(*unit)); unit->nr_cells = nr_cells; for (i = 0; i < unit->nr_cells; i++) { unit->cells[i] = BE2H_cell(*cell); cell += 1; } return cell;}STATIC_INLINE_DEVICE\(unsigned)nr_range_property_cells(device *me, int nr_ranges){ return ((device_nr_address_cells(me) + device_nr_address_cells(device_parent(me)) + device_nr_size_cells(me)) ) * nr_ranges;}INLINE_DEVICE\(void)device_add_range_array_property(device *me, const char *property, const range_property_spec *ranges, unsigned nr_ranges){ unsigned sizeof_cells = (nr_range_property_cells(me, nr_ranges) * sizeof(unsigned_cell)); unsigned_cell *cells = zalloc(sizeof_cells); unsigned_cell *cell; int i; /* copy the property elements over */ cell = cells; for (i = 0; i < nr_ranges; i++) { const range_property_spec *range = &ranges[i]; /* copy the child address */ cell = unit_address_to_cells(&range->child_address, cell, device_nr_address_cells(me)); /* copy the parent address */ cell = unit_address_to_cells(&range->parent_address, cell, device_nr_address_cells(device_parent(me))); /* copy the size */ cell = unit_address_to_cells(&range->size, cell, device_nr_size_cells(me)); } ASSERT(cell == &cells[nr_range_property_cells(me, nr_ranges)]); /* add it */ device_add_property(me, property, range_array_property, cells, sizeof_cells, cells, sizeof_cells, NULL, permenant_object); zfree(cells);}INLINE_DEVICE\(int)device_find_range_array_property(device *me, const char *property, unsigned index, range_property_spec *range){ const device_property *node; unsigned sizeof_entry = (nr_range_property_cells(me, 1) * sizeof(unsigned_cell)); const unsigned_cell *cells; /* locate the property */ node = device_find_property(me, property); if (node == (device_property*)0 || node->type != range_array_property) device_error(me, "property %s not found or of wrong type", property); /* aligned ? */ if ((node->sizeof_array % sizeof_entry) != 0) device_error(me, "property %s contains an incomplete number of entries", property); /* within bounds? */ if (node->sizeof_array < sizeof_entry * (index + 1)) return 0; /* find the range of interest */ cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index); /* copy the child address out - converting as we go */ cells = cells_to_unit_address(cells, &range->child_address, device_nr_address_cells(me)); /* copy the parent address out - converting as we go */ cells = cells_to_unit_address(cells, &range->parent_address, device_nr_address_cells(device_parent(me))); /* copy the size - converting as we go */ cells = cells_to_unit_address(cells, &range->size, device_nr_size_cells(me)); return node->sizeof_array / sizeof_entry;}STATIC_INLINE_DEVICE\(unsigned)nr_reg_property_cells(device *me, int nr_regs){ return (device_nr_address_cells(device_parent(me)) + device_nr_size_cells(device_parent(me)) ) * nr_regs;}INLINE_DEVICE\(void)device_add_reg_array_property(device *me, const char *property, const reg_property_spec *regs, unsigned nr_regs){ unsigned sizeof_cells = (nr_reg_property_cells(me, nr_regs) * sizeof(unsigned_cell)); unsigned_cell *cells = zalloc(sizeof_cells); unsigned_cell *cell; int i; /* copy the property elements over */ cell = cells; for (i = 0; i < nr_regs; i++) { const reg_property_spec *reg = ®s[i]; /* copy the address */ cell = unit_address_to_cells(®->address, cell, device_nr_address_cells(device_parent(me))); /* copy the size */ cell = unit_address_to_cells(®->size, cell, device_nr_size_cells(device_parent(me))); } ASSERT(cell == &cells[nr_reg_property_cells(me, nr_regs)]); /* add it */ device_add_property(me, property, reg_array_property, cells, sizeof_cells, cells, sizeof_cells, NULL, permenant_object); zfree(cells);}INLINE_DEVICE\(int)device_find_reg_array_property(device *me, const char *property, unsigned index, reg_property_spec *reg){ const device_property *node; unsigned sizeof_entry = (nr_reg_property_cells(me, 1) * sizeof(unsigned_cell)); const unsigned_cell *cells; /* locate the property */ node = device_find_property(me, property); if (node == (device_property*)0 || node->type != reg_array_property) device_error(me, "property %s not found or of wrong type", property); /* aligned ? */ if ((node->sizeof_array % sizeof_entry) != 0) device_error(me, "property %s contains an incomplete number of entries", property); /* within bounds? */ if (node->sizeof_array < sizeof_entry * (index + 1)) return 0; /* find the range of interest */ cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index); /* copy the address out - converting as we go */ cells = cells_to_unit_address(cells, ®->address, device_nr_address_cells(device_parent(me))); /* copy the size out - converting as we go */ cells = cells_to_unit_address(cells, ®->size, device_nr_size_cells(device_parent(me))); return node->sizeof_array / sizeof_entry;}INLINE_DEVICE\(void)device_add_string_property(device *me, const char *property, const char *string){ device_add_property(me, property, string_property, string, strlen(string) + 1, string, strlen(string) + 1, NULL, permenant_object);}INLINE_DEVICE\(const char *)device_find_string_property(device *me, const char *property){ const device_property *node; const char *string; node = device_find_property(me, property); if (node == (device_property*)0 || node->type != string_property) device_error(me, "property %s not found or of wrong type", property); string = node->array; ASSERT(strlen(string) + 1 == node->sizeof_array); return string;}INLINE_DEVICE\(void)device_add_string_array_property(device *me, const char *property, const string_property_spec *strings, unsigned nr_strings){ int sizeof_array; int string_nr; char *array; char *chp; if (nr_strings == 0) device_error(me, "property %s must be non-null", property); /* total up the size of the needed array */ for (sizeof_array = 0, string_nr = 0; string_nr < nr_strings; string_nr ++) { sizeof_array += strlen(strings[string_nr]) + 1; } /* create the array */ array = (char*)zalloc(sizeof_array); chp = array; for (string_nr = 0; string_nr < nr_strings; string_nr++) { strcpy(chp, strings[string_nr]); chp += strlen(chp) + 1; } ASSERT(chp == array + sizeof_array); /* now enter it */ device_add_property(me, property, string_array_property, array, sizeof_array, array, sizeof_array, NULL, permenant_object);}INLINE_DEVICE\(int)device_find_string_array_property(device *me, const char *property, unsigned index, string_property_spec *string){ const device_property *node; node = device_find_property(me, property); if (node == (device_property*)0) device_error(me, "property %s not found", property); switch (node->type) { default: device_error(me, "property %s of wrong type", property); break; case string_property: if (index == 0) { *string = node->array; ASSERT(strlen(*string) + 1 == node->sizeof_array); return 1; } break; case array_property: if (node->sizeof_array == 0 || ((char*)node->array)[node->sizeof_array - 1] != '\0') device_error(me, "property %s invalid for string array", property); /* FALL THROUGH */ case string_array_property: ASSERT(node->sizeof_array > 0); ASSERT(((char*)node->array)[node->sizeof_array - 1] == '\0'); { const char *chp = node->array; int nr_entries = 0; /* count the number of strings, keeping an eye out for the one we're looking for */ *string = chp; do { if (*chp == '\0') { /* next string */ nr_entries++; chp++; if (nr_entries == index) *string = chp; } else { chp++; } } while (chp < (char*)node->array + node->sizeof_array); if (index < nr_entries) return nr_entries; else { *string = NULL; return 0; } } break; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -