From 091ba358a815838b74ca907dda82a921a6a7e541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Wed, 15 Aug 2012 21:28:30 +0200 Subject: [PATCH 001/137] U-Boot: disable optimisation to help debugging * the U-Boot support code is yet unfinished and needs more debugging. --- src/system/boot/platform/u-boot/Jamfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/system/boot/platform/u-boot/Jamfile b/src/system/boot/platform/u-boot/Jamfile index 17327b84d4..dea0d99f23 100644 --- a/src/system/boot/platform/u-boot/Jamfile +++ b/src/system/boot/platform/u-boot/Jamfile @@ -18,8 +18,8 @@ UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) board $(TARGET_BOOT_BOAR local defines = _BOOT_MODE ; defines = [ FDefines $(defines) ] ; - SubDirCcFlags $(defines) -g3 ; - SubDirC++Flags $(defines) -fno-rtti -g3 ; + SubDirCcFlags $(defines) -g3 -O0 ; + SubDirC++Flags $(defines) -fno-rtti -g3 -O0 ; } # we fake NetBSD since we don't have an OS ID yet for uimage, From 53efe6a185ec42eac86f188e9d745068427ccdfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Wed, 22 Aug 2012 19:14:06 +0200 Subject: [PATCH 002/137] Add libfdt from dtc v1.3.0 * U-Boot based loader code will need to manipulate the passed Flattened Device Tree, no need to reinvent the wheel. * libfdt itself is dual-licensed GPL/BSD, the later suiting us. * This comes from tag v1.3.0 --- src/libs/libfdt/Makefile.libfdt | 10 + src/libs/libfdt/TODO | 3 + src/libs/libfdt/fdt.c | 222 ++++++ src/libs/libfdt/fdt.h | 60 ++ src/libs/libfdt/fdt_ro.c | 574 ++++++++++++++ src/libs/libfdt/fdt_rw.c | 465 +++++++++++ src/libs/libfdt/fdt_strerror.c | 96 +++ src/libs/libfdt/fdt_sw.c | 256 ++++++ src/libs/libfdt/fdt_wip.c | 118 +++ src/libs/libfdt/libfdt.h | 1235 +++++++++++++++++++++++++++++ src/libs/libfdt/libfdt_env.h | 23 + src/libs/libfdt/libfdt_internal.h | 95 +++ src/libs/libfdt/version.lds | 54 ++ 13 files changed, 3211 insertions(+) create mode 100644 src/libs/libfdt/Makefile.libfdt create mode 100644 src/libs/libfdt/TODO create mode 100644 src/libs/libfdt/fdt.c create mode 100644 src/libs/libfdt/fdt.h create mode 100644 src/libs/libfdt/fdt_ro.c create mode 100644 src/libs/libfdt/fdt_rw.c create mode 100644 src/libs/libfdt/fdt_strerror.c create mode 100644 src/libs/libfdt/fdt_sw.c create mode 100644 src/libs/libfdt/fdt_wip.c create mode 100644 src/libs/libfdt/libfdt.h create mode 100644 src/libs/libfdt/libfdt_env.h create mode 100644 src/libs/libfdt/libfdt_internal.h create mode 100644 src/libs/libfdt/version.lds diff --git a/src/libs/libfdt/Makefile.libfdt b/src/libs/libfdt/Makefile.libfdt new file mode 100644 index 0000000000..d55a6f852a --- /dev/null +++ b/src/libs/libfdt/Makefile.libfdt @@ -0,0 +1,10 @@ +# Makefile.libfdt +# +# This is not a complete Makefile of itself. Instead, it is designed to +# be easily embeddable into other systems of Makefiles. +# +LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1 +LIBFDT_INCLUDES = fdt.h libfdt.h +LIBFDT_VERSION = version.lds +LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c +LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o) diff --git a/src/libs/libfdt/TODO b/src/libs/libfdt/TODO new file mode 100644 index 0000000000..288437e394 --- /dev/null +++ b/src/libs/libfdt/TODO @@ -0,0 +1,3 @@ +- Tree traversal functions +- Graft function +- Complete libfdt.h documenting comments diff --git a/src/libs/libfdt/fdt.c b/src/libs/libfdt/fdt.c new file mode 100644 index 0000000000..e56833ae9b --- /dev/null +++ b/src/libs/libfdt/fdt.c @@ -0,0 +1,222 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * libfdt is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Alternatively, + * + * b) Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +int fdt_check_header(const void *fdt) +{ + if (fdt_magic(fdt) == FDT_MAGIC) { + /* Complete tree */ + if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) + return -FDT_ERR_BADVERSION; + if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) + return -FDT_ERR_BADVERSION; + } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { + /* Unfinished sequential-write blob */ + if (fdt_size_dt_struct(fdt) == 0) + return -FDT_ERR_BADSTATE; + } else { + return -FDT_ERR_BADMAGIC; + } + + return 0; +} + +const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) +{ + const char *p; + + if (fdt_version(fdt) >= 0x11) + if (((offset + len) < offset) + || ((offset + len) > fdt_size_dt_struct(fdt))) + return NULL; + + p = _fdt_offset_ptr(fdt, offset); + + if (p + len < p) + return NULL; + return p; +} + +uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) +{ + const uint32_t *tagp, *lenp; + uint32_t tag; + int offset = startoffset; + const char *p; + + *nextoffset = -FDT_ERR_TRUNCATED; + tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); + if (!tagp) + return FDT_END; /* premature end */ + tag = fdt32_to_cpu(*tagp); + offset += FDT_TAGSIZE; + + *nextoffset = -FDT_ERR_BADSTRUCTURE; + switch (tag) { + case FDT_BEGIN_NODE: + /* skip name */ + do { + p = fdt_offset_ptr(fdt, offset++, 1); + } while (p && (*p != '\0')); + if (!p) + return FDT_END; /* premature end */ + break; + + case FDT_PROP: + lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); + if (!lenp) + return FDT_END; /* premature end */ + /* skip-name offset, length and value */ + offset += sizeof(struct fdt_property) - FDT_TAGSIZE + + fdt32_to_cpu(*lenp); + break; + + case FDT_END: + case FDT_END_NODE: + case FDT_NOP: + break; + + default: + return FDT_END; + } + + if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset)) + return FDT_END; /* premature end */ + + *nextoffset = FDT_TAGALIGN(offset); + return tag; +} + +int _fdt_check_node_offset(const void *fdt, int offset) +{ + if ((offset < 0) || (offset % FDT_TAGSIZE) + || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE)) + return -FDT_ERR_BADOFFSET; + + return offset; +} + +int _fdt_check_prop_offset(const void *fdt, int offset) +{ + if ((offset < 0) || (offset % FDT_TAGSIZE) + || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP)) + return -FDT_ERR_BADOFFSET; + + return offset; +} + +int fdt_next_node(const void *fdt, int offset, int *depth) +{ + int nextoffset = 0; + uint32_t tag; + + if (offset >= 0) + if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0) + return nextoffset; + + do { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + + switch (tag) { + case FDT_PROP: + case FDT_NOP: + break; + + case FDT_BEGIN_NODE: + if (depth) + (*depth)++; + break; + + case FDT_END_NODE: + if (depth && ((--(*depth)) < 0)) + return nextoffset; + break; + + case FDT_END: + if ((nextoffset >= 0) + || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth)) + return -FDT_ERR_NOTFOUND; + else + return nextoffset; + } + } while (tag != FDT_BEGIN_NODE); + + return offset; +} + +const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) +{ + int len = strlen(s) + 1; + const char *last = strtab + tabsize - len; + const char *p; + + for (p = strtab; p <= last; p++) + if (memcmp(p, s, len) == 0) + return p; + return NULL; +} + +int fdt_move(const void *fdt, void *buf, int bufsize) +{ + FDT_CHECK_HEADER(fdt); + + if (fdt_totalsize(fdt) > bufsize) + return -FDT_ERR_NOSPACE; + + memmove(buf, fdt, fdt_totalsize(fdt)); + return 0; +} diff --git a/src/libs/libfdt/fdt.h b/src/libs/libfdt/fdt.h new file mode 100644 index 0000000000..48ccfd9100 --- /dev/null +++ b/src/libs/libfdt/fdt.h @@ -0,0 +1,60 @@ +#ifndef _FDT_H +#define _FDT_H + +#ifndef __ASSEMBLY__ + +struct fdt_header { + uint32_t magic; /* magic word FDT_MAGIC */ + uint32_t totalsize; /* total size of DT block */ + uint32_t off_dt_struct; /* offset to structure */ + uint32_t off_dt_strings; /* offset to strings */ + uint32_t off_mem_rsvmap; /* offset to memory reserve map */ + uint32_t version; /* format version */ + uint32_t last_comp_version; /* last compatible version */ + + /* version 2 fields below */ + uint32_t boot_cpuid_phys; /* Which physical CPU id we're + booting on */ + /* version 3 fields below */ + uint32_t size_dt_strings; /* size of the strings block */ + + /* version 17 fields below */ + uint32_t size_dt_struct; /* size of the structure block */ +}; + +struct fdt_reserve_entry { + uint64_t address; + uint64_t size; +}; + +struct fdt_node_header { + uint32_t tag; + char name[0]; +}; + +struct fdt_property { + uint32_t tag; + uint32_t len; + uint32_t nameoff; + char data[0]; +}; + +#endif /* !__ASSEMBLY */ + +#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ +#define FDT_TAGSIZE sizeof(uint32_t) + +#define FDT_BEGIN_NODE 0x1 /* Start node: full name */ +#define FDT_END_NODE 0x2 /* End node */ +#define FDT_PROP 0x3 /* Property: name off, + size, content */ +#define FDT_NOP 0x4 /* nop */ +#define FDT_END 0x9 + +#define FDT_V1_SIZE (7*sizeof(uint32_t)) +#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t)) +#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t)) +#define FDT_V16_SIZE FDT_V3_SIZE +#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t)) + +#endif /* _FDT_H */ diff --git a/src/libs/libfdt/fdt_ro.c b/src/libs/libfdt/fdt_ro.c new file mode 100644 index 0000000000..02b6d68753 --- /dev/null +++ b/src/libs/libfdt/fdt_ro.c @@ -0,0 +1,574 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * libfdt is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Alternatively, + * + * b) Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +static int _fdt_nodename_eq(const void *fdt, int offset, + const char *s, int len) +{ + const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); + + if (! p) + /* short match */ + return 0; + + if (memcmp(p, s, len) != 0) + return 0; + + if (p[len] == '\0') + return 1; + else if (!memchr(s, '@', len) && (p[len] == '@')) + return 1; + else + return 0; +} + +const char *fdt_string(const void *fdt, int stroffset) +{ + return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; +} + +static int _fdt_string_eq(const void *fdt, int stroffset, + const char *s, int len) +{ + const char *p = fdt_string(fdt, stroffset); + + return (strlen(p) == len) && (memcmp(p, s, len) == 0); +} + +int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) +{ + FDT_CHECK_HEADER(fdt); + *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address); + *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size); + return 0; +} + +int fdt_num_mem_rsv(const void *fdt) +{ + int i = 0; + + while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0) + i++; + return i; +} + +static int _nextprop(const void *fdt, int offset) +{ + uint32_t tag; + int nextoffset; + + do { + tag = fdt_next_tag(fdt, offset, &nextoffset); + + switch (tag) { + case FDT_END: + if (nextoffset >= 0) + return -FDT_ERR_BADSTRUCTURE; + else + return nextoffset; + + case FDT_PROP: + return offset; + } + offset = nextoffset; + } while (tag == FDT_NOP); + + return -FDT_ERR_NOTFOUND; +} + +int fdt_subnode_offset_namelen(const void *fdt, int offset, + const char *name, int namelen) +{ + int depth; + + FDT_CHECK_HEADER(fdt); + + for (depth = 0; + (offset >= 0) && (depth >= 0); + offset = fdt_next_node(fdt, offset, &depth)) + if ((depth == 1) + && _fdt_nodename_eq(fdt, offset, name, namelen)) + return offset; + + if (depth < 0) + return -FDT_ERR_NOTFOUND; + return offset; /* error */ +} + +int fdt_subnode_offset(const void *fdt, int parentoffset, + const char *name) +{ + return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); +} + +int fdt_path_offset(const void *fdt, const char *path) +{ + const char *end = path + strlen(path); + const char *p = path; + int offset = 0; + + FDT_CHECK_HEADER(fdt); + + /* see if we have an alias */ + if (*path != '/') { + const char *q = strchr(path, '/'); + + if (!q) + q = end; + + p = fdt_get_alias_namelen(fdt, p, q - p); + if (!p) + return -FDT_ERR_BADPATH; + offset = fdt_path_offset(fdt, p); + + p = q; + } + + while (*p) { + const char *q; + + while (*p == '/') + p++; + if (! *p) + return offset; + q = strchr(p, '/'); + if (! q) + q = end; + + offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); + if (offset < 0) + return offset; + + p = q; + } + + return offset; +} + +const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) +{ + const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset); + int err; + + if (((err = fdt_check_header(fdt)) != 0) + || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0)) + goto fail; + + if (len) + *len = strlen(nh->name); + + return nh->name; + + fail: + if (len) + *len = err; + return NULL; +} + +int fdt_first_property_offset(const void *fdt, int nodeoffset) +{ + int offset; + + if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) + return offset; + + return _nextprop(fdt, offset); +} + +int fdt_next_property_offset(const void *fdt, int offset) +{ + if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0) + return offset; + + return _nextprop(fdt, offset); +} + +const struct fdt_property *fdt_get_property_by_offset(const void *fdt, + int offset, + int *lenp) +{ + int err; + const struct fdt_property *prop; + + if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) { + if (lenp) + *lenp = err; + return NULL; + } + + prop = _fdt_offset_ptr(fdt, offset); + + if (lenp) + *lenp = fdt32_to_cpu(prop->len); + + return prop; +} + +const struct fdt_property *fdt_get_property_namelen(const void *fdt, + int offset, + const char *name, + int namelen, int *lenp) +{ + for (offset = fdt_first_property_offset(fdt, offset); + (offset >= 0); + (offset = fdt_next_property_offset(fdt, offset))) { + const struct fdt_property *prop; + + if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) { + offset = -FDT_ERR_INTERNAL; + break; + } + if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff), + name, namelen)) + return prop; + } + + if (lenp) + *lenp = offset; + return NULL; +} + +const struct fdt_property *fdt_get_property(const void *fdt, + int nodeoffset, + const char *name, int *lenp) +{ + return fdt_get_property_namelen(fdt, nodeoffset, name, + strlen(name), lenp); +} + +const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, + const char *name, int namelen, int *lenp) +{ + const struct fdt_property *prop; + + prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp); + if (! prop) + return NULL; + + return prop->data; +} + +const void *fdt_getprop_by_offset(const void *fdt, int offset, + const char **namep, int *lenp) +{ + const struct fdt_property *prop; + + prop = fdt_get_property_by_offset(fdt, offset, lenp); + if (!prop) + return NULL; + if (namep) + *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + return prop->data; +} + +const void *fdt_getprop(const void *fdt, int nodeoffset, + const char *name, int *lenp) +{ + return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp); +} + +uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) +{ + const uint32_t *php; + int len; + + /* FIXME: This is a bit sub-optimal, since we potentially scan + * over all the properties twice. */ + php = fdt_getprop(fdt, nodeoffset, "phandle", &len); + if (!php || (len != sizeof(*php))) { + php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len); + if (!php || (len != sizeof(*php))) + return 0; + } + + return fdt32_to_cpu(*php); +} + +const char *fdt_get_alias_namelen(const void *fdt, + const char *name, int namelen) +{ + int aliasoffset; + + aliasoffset = fdt_path_offset(fdt, "/aliases"); + if (aliasoffset < 0) + return NULL; + + return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL); +} + +const char *fdt_get_alias(const void *fdt, const char *name) +{ + return fdt_get_alias_namelen(fdt, name, strlen(name)); +} + +int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) +{ + int pdepth = 0, p = 0; + int offset, depth, namelen; + const char *name; + + FDT_CHECK_HEADER(fdt); + + if (buflen < 2) + return -FDT_ERR_NOSPACE; + + for (offset = 0, depth = 0; + (offset >= 0) && (offset <= nodeoffset); + offset = fdt_next_node(fdt, offset, &depth)) { + while (pdepth > depth) { + do { + p--; + } while (buf[p-1] != '/'); + pdepth--; + } + + if (pdepth >= depth) { + name = fdt_get_name(fdt, offset, &namelen); + if (!name) + return namelen; + if ((p + namelen + 1) <= buflen) { + memcpy(buf + p, name, namelen); + p += namelen; + buf[p++] = '/'; + pdepth++; + } + } + + if (offset == nodeoffset) { + if (pdepth < (depth + 1)) + return -FDT_ERR_NOSPACE; + + if (p > 1) /* special case so that root path is "/", not "" */ + p--; + buf[p] = '\0'; + return 0; + } + } + + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) + return -FDT_ERR_BADOFFSET; + else if (offset == -FDT_ERR_BADOFFSET) + return -FDT_ERR_BADSTRUCTURE; + + return offset; /* error from fdt_next_node() */ +} + +int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, + int supernodedepth, int *nodedepth) +{ + int offset, depth; + int supernodeoffset = -FDT_ERR_INTERNAL; + + FDT_CHECK_HEADER(fdt); + + if (supernodedepth < 0) + return -FDT_ERR_NOTFOUND; + + for (offset = 0, depth = 0; + (offset >= 0) && (offset <= nodeoffset); + offset = fdt_next_node(fdt, offset, &depth)) { + if (depth == supernodedepth) + supernodeoffset = offset; + + if (offset == nodeoffset) { + if (nodedepth) + *nodedepth = depth; + + if (supernodedepth > depth) + return -FDT_ERR_NOTFOUND; + else + return supernodeoffset; + } + } + + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) + return -FDT_ERR_BADOFFSET; + else if (offset == -FDT_ERR_BADOFFSET) + return -FDT_ERR_BADSTRUCTURE; + + return offset; /* error from fdt_next_node() */ +} + +int fdt_node_depth(const void *fdt, int nodeoffset) +{ + int nodedepth; + int err; + + err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth); + if (err) + return (err < 0) ? err : -FDT_ERR_INTERNAL; + return nodedepth; +} + +int fdt_parent_offset(const void *fdt, int nodeoffset) +{ + int nodedepth = fdt_node_depth(fdt, nodeoffset); + + if (nodedepth < 0) + return nodedepth; + return fdt_supernode_atdepth_offset(fdt, nodeoffset, + nodedepth - 1, NULL); +} + +int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, + const char *propname, + const void *propval, int proplen) +{ + int offset; + const void *val; + int len; + + FDT_CHECK_HEADER(fdt); + + /* FIXME: The algorithm here is pretty horrible: we scan each + * property of a node in fdt_getprop(), then if that didn't + * find what we want, we scan over them again making our way + * to the next node. Still it's the easiest to implement + * approach; performance can come later. */ + for (offset = fdt_next_node(fdt, startoffset, NULL); + offset >= 0; + offset = fdt_next_node(fdt, offset, NULL)) { + val = fdt_getprop(fdt, offset, propname, &len); + if (val && (len == proplen) + && (memcmp(val, propval, len) == 0)) + return offset; + } + + return offset; /* error from fdt_next_node() */ +} + +int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) +{ + int offset; + + if ((phandle == 0) || (phandle == -1)) + return -FDT_ERR_BADPHANDLE; + + FDT_CHECK_HEADER(fdt); + + /* FIXME: The algorithm here is pretty horrible: we + * potentially scan each property of a node in + * fdt_get_phandle(), then if that didn't find what + * we want, we scan over them again making our way to the next + * node. Still it's the easiest to implement approach; + * performance can come later. */ + for (offset = fdt_next_node(fdt, -1, NULL); + offset >= 0; + offset = fdt_next_node(fdt, offset, NULL)) { + if (fdt_get_phandle(fdt, offset) == phandle) + return offset; + } + + return offset; /* error from fdt_next_node() */ +} + +static int _fdt_stringlist_contains(const char *strlist, int listlen, + const char *str) +{ + int len = strlen(str); + const char *p; + + while (listlen >= len) { + if (memcmp(str, strlist, len+1) == 0) + return 1; + p = memchr(strlist, '\0', listlen); + if (!p) + return 0; /* malformed strlist.. */ + listlen -= (p-strlist) + 1; + strlist = p + 1; + } + return 0; +} + +int fdt_node_check_compatible(const void *fdt, int nodeoffset, + const char *compatible) +{ + const void *prop; + int len; + + prop = fdt_getprop(fdt, nodeoffset, "compatible", &len); + if (!prop) + return len; + if (_fdt_stringlist_contains(prop, len, compatible)) + return 0; + else + return 1; +} + +int fdt_node_offset_by_compatible(const void *fdt, int startoffset, + const char *compatible) +{ + int offset, err; + + FDT_CHECK_HEADER(fdt); + + /* FIXME: The algorithm here is pretty horrible: we scan each + * property of a node in fdt_node_check_compatible(), then if + * that didn't find what we want, we scan over them again + * making our way to the next node. Still it's the easiest to + * implement approach; performance can come later. */ + for (offset = fdt_next_node(fdt, startoffset, NULL); + offset >= 0; + offset = fdt_next_node(fdt, offset, NULL)) { + err = fdt_node_check_compatible(fdt, offset, compatible); + if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) + return err; + else if (err == 0) + return offset; + } + + return offset; /* error from fdt_next_node() */ +} diff --git a/src/libs/libfdt/fdt_rw.c b/src/libs/libfdt/fdt_rw.c new file mode 100644 index 0000000000..994037bbbd --- /dev/null +++ b/src/libs/libfdt/fdt_rw.c @@ -0,0 +1,465 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * libfdt is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Alternatively, + * + * b) Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +static int _fdt_blocks_misordered(const void *fdt, + int mem_rsv_size, int struct_size) +{ + return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8)) + || (fdt_off_dt_struct(fdt) < + (fdt_off_mem_rsvmap(fdt) + mem_rsv_size)) + || (fdt_off_dt_strings(fdt) < + (fdt_off_dt_struct(fdt) + struct_size)) + || (fdt_totalsize(fdt) < + (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); +} + +static int _fdt_rw_check_header(void *fdt) +{ + FDT_CHECK_HEADER(fdt); + + if (fdt_version(fdt) < 17) + return -FDT_ERR_BADVERSION; + if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry), + fdt_size_dt_struct(fdt))) + return -FDT_ERR_BADLAYOUT; + if (fdt_version(fdt) > 17) + fdt_set_version(fdt, 17); + + return 0; +} + +#define FDT_RW_CHECK_HEADER(fdt) \ + { \ + int err; \ + if ((err = _fdt_rw_check_header(fdt)) != 0) \ + return err; \ + } + +static inline int _fdt_data_size(void *fdt) +{ + return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); +} + +static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen) +{ + char *p = splicepoint; + char *end = (char *)fdt + _fdt_data_size(fdt); + + if (((p + oldlen) < p) || ((p + oldlen) > end)) + return -FDT_ERR_BADOFFSET; + if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt))) + return -FDT_ERR_NOSPACE; + memmove(p + newlen, p + oldlen, end - p - oldlen); + return 0; +} + +static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, + int oldn, int newn) +{ + int delta = (newn - oldn) * sizeof(*p); + int err; + err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); + if (err) + return err; + fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta); + fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta); + return 0; +} + +static int _fdt_splice_struct(void *fdt, void *p, + int oldlen, int newlen) +{ + int delta = newlen - oldlen; + int err; + + if ((err = _fdt_splice(fdt, p, oldlen, newlen))) + return err; + + fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta); + fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta); + return 0; +} + +static int _fdt_splice_string(void *fdt, int newlen) +{ + void *p = (char *)fdt + + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); + int err; + + if ((err = _fdt_splice(fdt, p, 0, newlen))) + return err; + + fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen); + return 0; +} + +static int _fdt_find_add_string(void *fdt, const char *s) +{ + char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); + const char *p; + char *new; + int len = strlen(s) + 1; + int err; + + p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s); + if (p) + /* found it */ + return (p - strtab); + + new = strtab + fdt_size_dt_strings(fdt); + err = _fdt_splice_string(fdt, len); + if (err) + return err; + + memcpy(new, s, len); + return (new - strtab); +} + +int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) +{ + struct fdt_reserve_entry *re; + int err; + + FDT_RW_CHECK_HEADER(fdt); + + re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt)); + err = _fdt_splice_mem_rsv(fdt, re, 0, 1); + if (err) + return err; + + re->address = cpu_to_fdt64(address); + re->size = cpu_to_fdt64(size); + return 0; +} + +int fdt_del_mem_rsv(void *fdt, int n) +{ + struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); + int err; + + FDT_RW_CHECK_HEADER(fdt); + + if (n >= fdt_num_mem_rsv(fdt)) + return -FDT_ERR_NOTFOUND; + + err = _fdt_splice_mem_rsv(fdt, re, 1, 0); + if (err) + return err; + return 0; +} + +static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, + int len, struct fdt_property **prop) +{ + int oldlen; + int err; + + *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); + if (! (*prop)) + return oldlen; + + if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), + FDT_TAGALIGN(len)))) + return err; + + (*prop)->len = cpu_to_fdt32(len); + return 0; +} + +static int _fdt_add_property(void *fdt, int nodeoffset, const char *name, + int len, struct fdt_property **prop) +{ + int proplen; + int nextoffset; + int namestroff; + int err; + + if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) + return nextoffset; + + namestroff = _fdt_find_add_string(fdt, name); + if (namestroff < 0) + return namestroff; + + *prop = _fdt_offset_ptr_w(fdt, nextoffset); + proplen = sizeof(**prop) + FDT_TAGALIGN(len); + + err = _fdt_splice_struct(fdt, *prop, 0, proplen); + if (err) + return err; + + (*prop)->tag = cpu_to_fdt32(FDT_PROP); + (*prop)->nameoff = cpu_to_fdt32(namestroff); + (*prop)->len = cpu_to_fdt32(len); + return 0; +} + +int fdt_set_name(void *fdt, int nodeoffset, const char *name) +{ + char *namep; + int oldlen, newlen; + int err; + + FDT_RW_CHECK_HEADER(fdt); + + namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen); + if (!namep) + return oldlen; + + newlen = strlen(name); + + err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1), + FDT_TAGALIGN(newlen+1)); + if (err) + return err; + + memcpy(namep, name, newlen+1); + return 0; +} + +int fdt_setprop(void *fdt, int nodeoffset, const char *name, + const void *val, int len) +{ + struct fdt_property *prop; + int err; + + FDT_RW_CHECK_HEADER(fdt); + + err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop); + if (err == -FDT_ERR_NOTFOUND) + err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); + if (err) + return err; + + memcpy(prop->data, val, len); + return 0; +} + +int fdt_delprop(void *fdt, int nodeoffset, const char *name) +{ + struct fdt_property *prop; + int len, proplen; + + FDT_RW_CHECK_HEADER(fdt); + + prop = fdt_get_property_w(fdt, nodeoffset, name, &len); + if (! prop) + return len; + + proplen = sizeof(*prop) + FDT_TAGALIGN(len); + return _fdt_splice_struct(fdt, prop, proplen, 0); +} + +int fdt_add_subnode_namelen(void *fdt, int parentoffset, + const char *name, int namelen) +{ + struct fdt_node_header *nh; + int offset, nextoffset; + int nodelen; + int err; + uint32_t tag; + uint32_t *endtag; + + FDT_RW_CHECK_HEADER(fdt); + + offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); + if (offset >= 0) + return -FDT_ERR_EXISTS; + else if (offset != -FDT_ERR_NOTFOUND) + return offset; + + /* Try to place the new node after the parent's properties */ + fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */ + do { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + } while ((tag == FDT_PROP) || (tag == FDT_NOP)); + + nh = _fdt_offset_ptr_w(fdt, offset); + nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE; + + err = _fdt_splice_struct(fdt, nh, 0, nodelen); + if (err) + return err; + + nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); + memset(nh->name, 0, FDT_TAGALIGN(namelen+1)); + memcpy(nh->name, name, namelen); + endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE); + *endtag = cpu_to_fdt32(FDT_END_NODE); + + return offset; +} + +int fdt_add_subnode(void *fdt, int parentoffset, const char *name) +{ + return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name)); +} + +int fdt_del_node(void *fdt, int nodeoffset) +{ + int endoffset; + + FDT_RW_CHECK_HEADER(fdt); + + endoffset = _fdt_node_end_offset(fdt, nodeoffset); + if (endoffset < 0) + return endoffset; + + return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset), + endoffset - nodeoffset, 0); +} + +static void _fdt_packblocks(const char *old, char *new, + int mem_rsv_size, int struct_size) +{ + int mem_rsv_off, struct_off, strings_off; + + mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8); + struct_off = mem_rsv_off + mem_rsv_size; + strings_off = struct_off + struct_size; + + memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size); + fdt_set_off_mem_rsvmap(new, mem_rsv_off); + + memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size); + fdt_set_off_dt_struct(new, struct_off); + fdt_set_size_dt_struct(new, struct_size); + + memmove(new + strings_off, old + fdt_off_dt_strings(old), + fdt_size_dt_strings(old)); + fdt_set_off_dt_strings(new, strings_off); + fdt_set_size_dt_strings(new, fdt_size_dt_strings(old)); +} + +int fdt_open_into(const void *fdt, void *buf, int bufsize) +{ + int err; + int mem_rsv_size, struct_size; + int newsize; + const char *fdtstart = fdt; + const char *fdtend = fdtstart + fdt_totalsize(fdt); + char *tmp; + + FDT_CHECK_HEADER(fdt); + + mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) + * sizeof(struct fdt_reserve_entry); + + if (fdt_version(fdt) >= 17) { + struct_size = fdt_size_dt_struct(fdt); + } else { + struct_size = 0; + while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END) + ; + if (struct_size < 0) + return struct_size; + } + + if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) { + /* no further work necessary */ + err = fdt_move(fdt, buf, bufsize); + if (err) + return err; + fdt_set_version(buf, 17); + fdt_set_size_dt_struct(buf, struct_size); + fdt_set_totalsize(buf, bufsize); + return 0; + } + + /* Need to reorder */ + newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size + + struct_size + fdt_size_dt_strings(fdt); + + if (bufsize < newsize) + return -FDT_ERR_NOSPACE; + + /* First attempt to build converted tree at beginning of buffer */ + tmp = buf; + /* But if that overlaps with the old tree... */ + if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) { + /* Try right after the old tree instead */ + tmp = (char *)(uintptr_t)fdtend; + if ((tmp + newsize) > ((char *)buf + bufsize)) + return -FDT_ERR_NOSPACE; + } + + _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size); + memmove(buf, tmp, newsize); + + fdt_set_magic(buf, FDT_MAGIC); + fdt_set_totalsize(buf, bufsize); + fdt_set_version(buf, 17); + fdt_set_last_comp_version(buf, 16); + fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt)); + + return 0; +} + +int fdt_pack(void *fdt) +{ + int mem_rsv_size; + + FDT_RW_CHECK_HEADER(fdt); + + mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) + * sizeof(struct fdt_reserve_entry); + _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); + fdt_set_totalsize(fdt, _fdt_data_size(fdt)); + + return 0; +} diff --git a/src/libs/libfdt/fdt_strerror.c b/src/libs/libfdt/fdt_strerror.c new file mode 100644 index 0000000000..e6c3ceee8c --- /dev/null +++ b/src/libs/libfdt/fdt_strerror.c @@ -0,0 +1,96 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * libfdt is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Alternatively, + * + * b) Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +struct fdt_errtabent { + const char *str; +}; + +#define FDT_ERRTABENT(val) \ + [(val)] = { .str = #val, } + +static struct fdt_errtabent fdt_errtable[] = { + FDT_ERRTABENT(FDT_ERR_NOTFOUND), + FDT_ERRTABENT(FDT_ERR_EXISTS), + FDT_ERRTABENT(FDT_ERR_NOSPACE), + + FDT_ERRTABENT(FDT_ERR_BADOFFSET), + FDT_ERRTABENT(FDT_ERR_BADPATH), + FDT_ERRTABENT(FDT_ERR_BADSTATE), + + FDT_ERRTABENT(FDT_ERR_TRUNCATED), + FDT_ERRTABENT(FDT_ERR_BADMAGIC), + FDT_ERRTABENT(FDT_ERR_BADVERSION), + FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE), + FDT_ERRTABENT(FDT_ERR_BADLAYOUT), +}; +#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0])) + +const char *fdt_strerror(int errval) +{ + if (errval > 0) + return ""; + else if (errval == 0) + return ""; + else if (errval > -FDT_ERRTABSIZE) { + const char *s = fdt_errtable[-errval].str; + + if (s) + return s; + } + + return ""; +} diff --git a/src/libs/libfdt/fdt_sw.c b/src/libs/libfdt/fdt_sw.c new file mode 100644 index 0000000000..55ebebf1eb --- /dev/null +++ b/src/libs/libfdt/fdt_sw.c @@ -0,0 +1,256 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * libfdt is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Alternatively, + * + * b) Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +static int _fdt_sw_check_header(void *fdt) +{ + if (fdt_magic(fdt) != FDT_SW_MAGIC) + return -FDT_ERR_BADMAGIC; + /* FIXME: should check more details about the header state */ + return 0; +} + +#define FDT_SW_CHECK_HEADER(fdt) \ + { \ + int err; \ + if ((err = _fdt_sw_check_header(fdt)) != 0) \ + return err; \ + } + +static void *_fdt_grab_space(void *fdt, size_t len) +{ + int offset = fdt_size_dt_struct(fdt); + int spaceleft; + + spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt) + - fdt_size_dt_strings(fdt); + + if ((offset + len < offset) || (offset + len > spaceleft)) + return NULL; + + fdt_set_size_dt_struct(fdt, offset + len); + return _fdt_offset_ptr_w(fdt, offset); +} + +int fdt_create(void *buf, int bufsize) +{ + void *fdt = buf; + + if (bufsize < sizeof(struct fdt_header)) + return -FDT_ERR_NOSPACE; + + memset(buf, 0, bufsize); + + fdt_set_magic(fdt, FDT_SW_MAGIC); + fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION); + fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION); + fdt_set_totalsize(fdt, bufsize); + + fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header), + sizeof(struct fdt_reserve_entry))); + fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); + fdt_set_off_dt_strings(fdt, bufsize); + + return 0; +} + +int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) +{ + struct fdt_reserve_entry *re; + int offset; + + FDT_SW_CHECK_HEADER(fdt); + + if (fdt_size_dt_struct(fdt)) + return -FDT_ERR_BADSTATE; + + offset = fdt_off_dt_struct(fdt); + if ((offset + sizeof(*re)) > fdt_totalsize(fdt)) + return -FDT_ERR_NOSPACE; + + re = (struct fdt_reserve_entry *)((char *)fdt + offset); + re->address = cpu_to_fdt64(addr); + re->size = cpu_to_fdt64(size); + + fdt_set_off_dt_struct(fdt, offset + sizeof(*re)); + + return 0; +} + +int fdt_finish_reservemap(void *fdt) +{ + return fdt_add_reservemap_entry(fdt, 0, 0); +} + +int fdt_begin_node(void *fdt, const char *name) +{ + struct fdt_node_header *nh; + int namelen = strlen(name) + 1; + + FDT_SW_CHECK_HEADER(fdt); + + nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); + if (! nh) + return -FDT_ERR_NOSPACE; + + nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); + memcpy(nh->name, name, namelen); + return 0; +} + +int fdt_end_node(void *fdt) +{ + uint32_t *en; + + FDT_SW_CHECK_HEADER(fdt); + + en = _fdt_grab_space(fdt, FDT_TAGSIZE); + if (! en) + return -FDT_ERR_NOSPACE; + + *en = cpu_to_fdt32(FDT_END_NODE); + return 0; +} + +static int _fdt_find_add_string(void *fdt, const char *s) +{ + char *strtab = (char *)fdt + fdt_totalsize(fdt); + const char *p; + int strtabsize = fdt_size_dt_strings(fdt); + int len = strlen(s) + 1; + int struct_top, offset; + + p = _fdt_find_string(strtab - strtabsize, strtabsize, s); + if (p) + return p - strtab; + + /* Add it */ + offset = -strtabsize - len; + struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); + if (fdt_totalsize(fdt) + offset < struct_top) + return 0; /* no more room :( */ + + memcpy(strtab + offset, s, len); + fdt_set_size_dt_strings(fdt, strtabsize + len); + return offset; +} + +int fdt_property(void *fdt, const char *name, const void *val, int len) +{ + struct fdt_property *prop; + int nameoff; + + FDT_SW_CHECK_HEADER(fdt); + + nameoff = _fdt_find_add_string(fdt, name); + if (nameoff == 0) + return -FDT_ERR_NOSPACE; + + prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); + if (! prop) + return -FDT_ERR_NOSPACE; + + prop->tag = cpu_to_fdt32(FDT_PROP); + prop->nameoff = cpu_to_fdt32(nameoff); + prop->len = cpu_to_fdt32(len); + memcpy(prop->data, val, len); + return 0; +} + +int fdt_finish(void *fdt) +{ + char *p = (char *)fdt; + uint32_t *end; + int oldstroffset, newstroffset; + uint32_t tag; + int offset, nextoffset; + + FDT_SW_CHECK_HEADER(fdt); + + /* Add terminator */ + end = _fdt_grab_space(fdt, sizeof(*end)); + if (! end) + return -FDT_ERR_NOSPACE; + *end = cpu_to_fdt32(FDT_END); + + /* Relocate the string table */ + oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt); + newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); + memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt)); + fdt_set_off_dt_strings(fdt, newstroffset); + + /* Walk the structure, correcting string offsets */ + offset = 0; + while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { + if (tag == FDT_PROP) { + struct fdt_property *prop = + _fdt_offset_ptr_w(fdt, offset); + int nameoff; + + nameoff = fdt32_to_cpu(prop->nameoff); + nameoff += fdt_size_dt_strings(fdt); + prop->nameoff = cpu_to_fdt32(nameoff); + } + offset = nextoffset; + } + if (nextoffset < 0) + return nextoffset; + + /* Finally, adjust the header */ + fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt)); + fdt_set_magic(fdt, FDT_MAGIC); + return 0; +} diff --git a/src/libs/libfdt/fdt_wip.c b/src/libs/libfdt/fdt_wip.c new file mode 100644 index 0000000000..6025fa1fe8 --- /dev/null +++ b/src/libs/libfdt/fdt_wip.c @@ -0,0 +1,118 @@ +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * libfdt is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Alternatively, + * + * b) Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, + const void *val, int len) +{ + void *propval; + int proplen; + + propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen); + if (! propval) + return proplen; + + if (proplen != len) + return -FDT_ERR_NOSPACE; + + memcpy(propval, val, len); + return 0; +} + +static void _fdt_nop_region(void *start, int len) +{ + uint32_t *p; + + for (p = start; (char *)p < ((char *)start + len); p++) + *p = cpu_to_fdt32(FDT_NOP); +} + +int fdt_nop_property(void *fdt, int nodeoffset, const char *name) +{ + struct fdt_property *prop; + int len; + + prop = fdt_get_property_w(fdt, nodeoffset, name, &len); + if (! prop) + return len; + + _fdt_nop_region(prop, len + sizeof(*prop)); + + return 0; +} + +int _fdt_node_end_offset(void *fdt, int offset) +{ + int depth = 0; + + while ((offset >= 0) && (depth >= 0)) + offset = fdt_next_node(fdt, offset, &depth); + + return offset; +} + +int fdt_nop_node(void *fdt, int nodeoffset) +{ + int endoffset; + + endoffset = _fdt_node_end_offset(fdt, nodeoffset); + if (endoffset < 0) + return endoffset; + + _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), + endoffset - nodeoffset); + return 0; +} diff --git a/src/libs/libfdt/libfdt.h b/src/libs/libfdt/libfdt.h new file mode 100644 index 0000000000..55f3eb3042 --- /dev/null +++ b/src/libs/libfdt/libfdt.h @@ -0,0 +1,1235 @@ +#ifndef _LIBFDT_H +#define _LIBFDT_H +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * libfdt is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Alternatively, + * + * b) Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#define FDT_FIRST_SUPPORTED_VERSION 0x10 +#define FDT_LAST_SUPPORTED_VERSION 0x11 + +/* Error codes: informative error codes */ +#define FDT_ERR_NOTFOUND 1 + /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ +#define FDT_ERR_EXISTS 2 + /* FDT_ERR_EXISTS: Attemped to create a node or property which + * already exists */ +#define FDT_ERR_NOSPACE 3 + /* FDT_ERR_NOSPACE: Operation needed to expand the device + * tree, but its buffer did not have sufficient space to + * contain the expanded tree. Use fdt_open_into() to move the + * device tree to a buffer with more space. */ + +/* Error codes: codes for bad parameters */ +#define FDT_ERR_BADOFFSET 4 + /* FDT_ERR_BADOFFSET: Function was passed a structure block + * offset which is out-of-bounds, or which points to an + * unsuitable part of the structure for the operation. */ +#define FDT_ERR_BADPATH 5 + /* FDT_ERR_BADPATH: Function was passed a badly formatted path + * (e.g. missing a leading / for a function which requires an + * absolute path) */ +#define FDT_ERR_BADPHANDLE 6 + /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle + * value. phandle values of 0 and -1 are not permitted. */ +#define FDT_ERR_BADSTATE 7 + /* FDT_ERR_BADSTATE: Function was passed an incomplete device + * tree created by the sequential-write functions, which is + * not sufficiently complete for the requested operation. */ + +/* Error codes: codes for bad device tree blobs */ +#define FDT_ERR_TRUNCATED 8 + /* FDT_ERR_TRUNCATED: Structure block of the given device tree + * ends without an FDT_END tag. */ +#define FDT_ERR_BADMAGIC 9 + /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a + * device tree at all - it is missing the flattened device + * tree magic number. */ +#define FDT_ERR_BADVERSION 10 + /* FDT_ERR_BADVERSION: Given device tree has a version which + * can't be handled by the requested operation. For + * read-write functions, this may mean that fdt_open_into() is + * required to convert the tree to the expected version. */ +#define FDT_ERR_BADSTRUCTURE 11 + /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt + * structure block or other serious error (e.g. misnested + * nodes, or subnodes preceding properties). */ +#define FDT_ERR_BADLAYOUT 12 + /* FDT_ERR_BADLAYOUT: For read-write functions, the given + * device tree has it's sub-blocks in an order that the + * function can't handle (memory reserve map, then structure, + * then strings). Use fdt_open_into() to reorganize the tree + * into a form suitable for the read-write operations. */ + +/* "Can't happen" error indicating a bug in libfdt */ +#define FDT_ERR_INTERNAL 13 + /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion. + * Should never be returned, if it is, it indicates a bug in + * libfdt itself. */ + +#define FDT_ERR_MAX 13 + +/**********************************************************************/ +/* Low-level functions (you probably don't need these) */ +/**********************************************************************/ + +const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen); +static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) +{ + return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen); +} + +uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); + +/**********************************************************************/ +/* Traversal functions */ +/**********************************************************************/ + +int fdt_next_node(const void *fdt, int offset, int *depth); + +/**********************************************************************/ +/* General functions */ +/**********************************************************************/ + +#define fdt_get_header(fdt, field) \ + (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) +#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) +#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) +#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) +#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) +#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) +#define fdt_version(fdt) (fdt_get_header(fdt, version)) +#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) +#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) +#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) +#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) + +#define __fdt_set_hdr(name) \ + static inline void fdt_set_##name(void *fdt, uint32_t val) \ + { \ + struct fdt_header *fdth = (struct fdt_header*)fdt; \ + fdth->name = cpu_to_fdt32(val); \ + } +__fdt_set_hdr(magic); +__fdt_set_hdr(totalsize); +__fdt_set_hdr(off_dt_struct); +__fdt_set_hdr(off_dt_strings); +__fdt_set_hdr(off_mem_rsvmap); +__fdt_set_hdr(version); +__fdt_set_hdr(last_comp_version); +__fdt_set_hdr(boot_cpuid_phys); +__fdt_set_hdr(size_dt_strings); +__fdt_set_hdr(size_dt_struct); +#undef __fdt_set_hdr + +/** + * fdt_check_header - sanity check a device tree or possible device tree + * @fdt: pointer to data which might be a flattened device tree + * + * fdt_check_header() checks that the given buffer contains what + * appears to be a flattened device tree with sane information in its + * header. + * + * returns: + * 0, if the buffer appears to contain a valid device tree + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, standard meanings, as above + */ +int fdt_check_header(const void *fdt); + +/** + * fdt_move - move a device tree around in memory + * @fdt: pointer to the device tree to move + * @buf: pointer to memory where the device is to be moved + * @bufsize: size of the memory space at buf + * + * fdt_move() relocates, if possible, the device tree blob located at + * fdt to the buffer at buf of size bufsize. The buffer may overlap + * with the existing device tree blob at fdt. Therefore, + * fdt_move(fdt, fdt, fdt_totalsize(fdt)) + * should always succeed. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, standard meanings + */ +int fdt_move(const void *fdt, void *buf, int bufsize); + +/**********************************************************************/ +/* Read-only functions */ +/**********************************************************************/ + +/** + * fdt_string - retrieve a string from the strings block of a device tree + * @fdt: pointer to the device tree blob + * @stroffset: offset of the string within the strings block (native endian) + * + * fdt_string() retrieves a pointer to a single string from the + * strings block of the device tree blob at fdt. + * + * returns: + * a pointer to the string, on success + * NULL, if stroffset is out of bounds + */ +const char *fdt_string(const void *fdt, int stroffset); + +/** + * fdt_num_mem_rsv - retrieve the number of memory reserve map entries + * @fdt: pointer to the device tree blob + * + * Returns the number of entries in the device tree blob's memory + * reservation map. This does not include the terminating 0,0 entry + * or any other (0,0) entries reserved for expansion. + * + * returns: + * the number of entries + */ +int fdt_num_mem_rsv(const void *fdt); + +/** + * fdt_get_mem_rsv - retrieve one memory reserve map entry + * @fdt: pointer to the device tree blob + * @address, @size: pointers to 64-bit variables + * + * On success, *address and *size will contain the address and size of + * the n-th reserve map entry from the device tree blob, in + * native-endian format. + * + * returns: + * 0, on success + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, standard meanings + */ +int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size); + +/** + * fdt_subnode_offset_namelen - find a subnode based on substring + * @fdt: pointer to the device tree blob + * @parentoffset: structure block offset of a node + * @name: name of the subnode to locate + * @namelen: number of characters of name to consider + * + * Identical to fdt_subnode_offset(), but only examine the first + * namelen characters of name for matching the subnode name. This is + * useful for finding subnodes based on a portion of a larger string, + * such as a full path. + */ +int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, + const char *name, int namelen); +/** + * fdt_subnode_offset - find a subnode of a given node + * @fdt: pointer to the device tree blob + * @parentoffset: structure block offset of a node + * @name: name of the subnode to locate + * + * fdt_subnode_offset() finds a subnode of the node at structure block + * offset parentoffset with the given name. name may include a unit + * address, in which case fdt_subnode_offset() will find the subnode + * with that unit address, or the unit address may be omitted, in + * which case fdt_subnode_offset() will find an arbitrary subnode + * whose name excluding unit address matches the given name. + * + * returns: + * structure block offset of the requested subnode (>=0), on success + * -FDT_ERR_NOTFOUND, if the requested subnode does not exist + * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings. + */ +int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); + +/** + * fdt_path_offset - find a tree node by its full path + * @fdt: pointer to the device tree blob + * @path: full path of the node to locate + * + * fdt_path_offset() finds a node of a given path in the device tree. + * Each path component may omit the unit address portion, but the + * results of this are undefined if any such path component is + * ambiguous (that is if there are multiple nodes at the relevant + * level matching the given component, differentiated only by unit + * address). + * + * returns: + * structure block offset of the node with the requested path (>=0), on success + * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid + * -FDT_ERR_NOTFOUND, if the requested node does not exist + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings. + */ +int fdt_path_offset(const void *fdt, const char *path); + +/** + * fdt_get_name - retrieve the name of a given node + * @fdt: pointer to the device tree blob + * @nodeoffset: structure block offset of the starting node + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_get_name() retrieves the name (including unit address) of the + * device tree node at structure block offset nodeoffset. If lenp is + * non-NULL, the length of this name is also returned, in the integer + * pointed to by lenp. + * + * returns: + * pointer to the node's name, on success + * If lenp is non-NULL, *lenp contains the length of that name (>=0) + * NULL, on error + * if lenp is non-NULL *lenp contains an error code (<0): + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, standard meanings + */ +const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp); + +/** + * fdt_first_property_offset - find the offset of a node's first property + * @fdt: pointer to the device tree blob + * @nodeoffset: structure block offset of a node + * + * fdt_first_property_offset() finds the first property of the node at + * the given structure block offset. + * + * returns: + * structure block offset of the property (>=0), on success + * -FDT_ERR_NOTFOUND, if the requested node has no properties + * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings. + */ +int fdt_first_property_offset(const void *fdt, int nodeoffset); + +/** + * fdt_next_property_offset - step through a node's properties + * @fdt: pointer to the device tree blob + * @offset: structure block offset of a property + * + * fdt_next_property_offset() finds the property immediately after the + * one at the given structure block offset. This will be a property + * of the same node as the given property. + * + * returns: + * structure block offset of the next property (>=0), on success + * -FDT_ERR_NOTFOUND, if the given property is the last in its node + * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings. + */ +int fdt_next_property_offset(const void *fdt, int offset); + +/** + * fdt_get_property_by_offset - retrieve the property at a given offset + * @fdt: pointer to the device tree blob + * @offset: offset of the property to retrieve + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_get_property_by_offset() retrieves a pointer to the + * fdt_property structure within the device tree blob at the given + * offset. If lenp is non-NULL, the length of the property value is + * also returned, in the integer pointed to by lenp. + * + * returns: + * pointer to the structure representing the property + * if lenp is non-NULL, *lenp contains the length of the property + * value (>=0) + * NULL, on error + * if lenp is non-NULL, *lenp contains an error code (<0): + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +const struct fdt_property *fdt_get_property_by_offset(const void *fdt, + int offset, + int *lenp); + +/** + * fdt_get_property_namelen - find a property based on substring + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to find + * @name: name of the property to find + * @namelen: number of characters of name to consider + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * Identical to fdt_get_property_namelen(), but only examine the first + * namelen characters of name for matching the property name. + */ +const struct fdt_property *fdt_get_property_namelen(const void *fdt, + int nodeoffset, + const char *name, + int namelen, int *lenp); + +/** + * fdt_get_property - find a given property in a given node + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to find + * @name: name of the property to find + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_get_property() retrieves a pointer to the fdt_property + * structure within the device tree blob corresponding to the property + * named 'name' of the node at offset nodeoffset. If lenp is + * non-NULL, the length of the property value is also returned, in the + * integer pointed to by lenp. + * + * returns: + * pointer to the structure representing the property + * if lenp is non-NULL, *lenp contains the length of the property + * value (>=0) + * NULL, on error + * if lenp is non-NULL, *lenp contains an error code (<0): + * -FDT_ERR_NOTFOUND, node does not have named property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, + const char *name, int *lenp); +static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, + const char *name, + int *lenp) +{ + return (struct fdt_property *)(uintptr_t) + fdt_get_property(fdt, nodeoffset, name, lenp); +} + +/** + * fdt_getprop_by_offset - retrieve the value of a property at a given offset + * @fdt: pointer to the device tree blob + * @ffset: offset of the property to read + * @namep: pointer to a string variable (will be overwritten) or NULL + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_getprop_by_offset() retrieves a pointer to the value of the + * property at structure block offset 'offset' (this will be a pointer + * to within the device blob itself, not a copy of the value). If + * lenp is non-NULL, the length of the property value is also + * returned, in the integer pointed to by lenp. If namep is non-NULL, + * the property's namne will also be returned in the char * pointed to + * by namep (this will be a pointer to within the device tree's string + * block, not a new copy of the name). + * + * returns: + * pointer to the property's value + * if lenp is non-NULL, *lenp contains the length of the property + * value (>=0) + * if namep is non-NULL *namep contiains a pointer to the property + * name. + * NULL, on error + * if lenp is non-NULL, *lenp contains an error code (<0): + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +const void *fdt_getprop_by_offset(const void *fdt, int offset, + const char **namep, int *lenp); + +/** + * fdt_getprop_namelen - get property value based on substring + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to find + * @name: name of the property to find + * @namelen: number of characters of name to consider + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * Identical to fdt_getprop(), but only examine the first namelen + * characters of name for matching the property name. + */ +const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, + const char *name, int namelen, int *lenp); + +/** + * fdt_getprop - retrieve the value of a given property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to find + * @name: name of the property to find + * @lenp: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_getprop() retrieves a pointer to the value of the property + * named 'name' of the node at offset nodeoffset (this will be a + * pointer to within the device blob itself, not a copy of the value). + * If lenp is non-NULL, the length of the property value is also + * returned, in the integer pointed to by lenp. + * + * returns: + * pointer to the property's value + * if lenp is non-NULL, *lenp contains the length of the property + * value (>=0) + * NULL, on error + * if lenp is non-NULL, *lenp contains an error code (<0): + * -FDT_ERR_NOTFOUND, node does not have named property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +const void *fdt_getprop(const void *fdt, int nodeoffset, + const char *name, int *lenp); +static inline void *fdt_getprop_w(void *fdt, int nodeoffset, + const char *name, int *lenp) +{ + return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp); +} + +/** + * fdt_get_phandle - retrieve the phandle of a given node + * @fdt: pointer to the device tree blob + * @nodeoffset: structure block offset of the node + * + * fdt_get_phandle() retrieves the phandle of the device tree node at + * structure block offset nodeoffset. + * + * returns: + * the phandle of the node at nodeoffset, on success (!= 0, != -1) + * 0, if the node has no phandle, or another error occurs + */ +uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); + +/** + * fdt_get_alias_namelen - get alias based on substring + * @fdt: pointer to the device tree blob + * @name: name of the alias th look up + * @namelen: number of characters of name to consider + * + * Identical to fdt_get_alias(), but only examine the first namelen + * characters of name for matching the alias name. + */ +const char *fdt_get_alias_namelen(const void *fdt, + const char *name, int namelen); + +/** + * fdt_get_alias - retreive the path referenced by a given alias + * @fdt: pointer to the device tree blob + * @name: name of the alias th look up + * + * fdt_get_alias() retrieves the value of a given alias. That is, the + * value of the property named 'name' in the node /aliases. + * + * returns: + * a pointer to the expansion of the alias named 'name', of it exists + * NULL, if the given alias or the /aliases node does not exist + */ +const char *fdt_get_alias(const void *fdt, const char *name); + +/** + * fdt_get_path - determine the full path of a node + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose path to find + * @buf: character buffer to contain the returned path (will be overwritten) + * @buflen: size of the character buffer at buf + * + * fdt_get_path() computes the full path of the node at offset + * nodeoffset, and records that path in the buffer at buf. + * + * NOTE: This function is expensive, as it must scan the device tree + * structure from the start to nodeoffset. + * + * returns: + * 0, on success + * buf contains the absolute path of the node at + * nodeoffset, as a NUL-terminated string. + * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1) + * characters and will not fit in the given buffer. + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); + +/** + * fdt_supernode_atdepth_offset - find a specific ancestor of a node + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose parent to find + * @supernodedepth: depth of the ancestor to find + * @nodedepth: pointer to an integer variable (will be overwritten) or NULL + * + * fdt_supernode_atdepth_offset() finds an ancestor of the given node + * at a specific depth from the root (where the root itself has depth + * 0, its immediate subnodes depth 1 and so forth). So + * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL); + * will always return 0, the offset of the root node. If the node at + * nodeoffset has depth D, then: + * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL); + * will return nodeoffset itself. + * + * NOTE: This function is expensive, as it must scan the device tree + * structure from the start to nodeoffset. + * + * returns: + + * structure block offset of the node at node offset's ancestor + * of depth supernodedepth (>=0), on success + * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag +* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, + int supernodedepth, int *nodedepth); + +/** + * fdt_node_depth - find the depth of a given node + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose parent to find + * + * fdt_node_depth() finds the depth of a given node. The root node + * has depth 0, its immediate subnodes depth 1 and so forth. + * + * NOTE: This function is expensive, as it must scan the device tree + * structure from the start to nodeoffset. + * + * returns: + * depth of the node at nodeoffset (>=0), on success + * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_node_depth(const void *fdt, int nodeoffset); + +/** + * fdt_parent_offset - find the parent of a given node + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose parent to find + * + * fdt_parent_offset() locates the parent node of a given node (that + * is, it finds the offset of the node which contains the node at + * nodeoffset as a subnode). + * + * NOTE: This function is expensive, as it must scan the device tree + * structure from the start to nodeoffset, *twice*. + * + * returns: + * structure block offset of the parent of the node at nodeoffset + * (>=0), on success + * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_parent_offset(const void *fdt, int nodeoffset); + +/** + * fdt_node_offset_by_prop_value - find nodes with a given property value + * @fdt: pointer to the device tree blob + * @startoffset: only find nodes after this offset + * @propname: property name to check + * @propval: property value to search for + * @proplen: length of the value in propval + * + * fdt_node_offset_by_prop_value() returns the offset of the first + * node after startoffset, which has a property named propname whose + * value is of length proplen and has value equal to propval; or if + * startoffset is -1, the very first such node in the tree. + * + * To iterate through all nodes matching the criterion, the following + * idiom can be used: + * offset = fdt_node_offset_by_prop_value(fdt, -1, propname, + * propval, proplen); + * while (offset != -FDT_ERR_NOTFOUND) { + * // other code here + * offset = fdt_node_offset_by_prop_value(fdt, offset, propname, + * propval, proplen); + * } + * + * Note the -1 in the first call to the function, if 0 is used here + * instead, the function will never locate the root node, even if it + * matches the criterion. + * + * returns: + * structure block offset of the located node (>= 0, >startoffset), + * on success + * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the + * tree after startoffset + * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, + const char *propname, + const void *propval, int proplen); + +/** + * fdt_node_offset_by_phandle - find the node with a given phandle + * @fdt: pointer to the device tree blob + * @phandle: phandle value + * + * fdt_node_offset_by_phandle() returns the offset of the node + * which has the given phandle value. If there is more than one node + * in the tree with the given phandle (an invalid tree), results are + * undefined. + * + * returns: + * structure block offset of the located node (>= 0), on success + * -FDT_ERR_NOTFOUND, no node with that phandle exists + * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1) + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); + +/** + * fdt_node_check_compatible: check a node's compatible property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of a tree node + * @compatible: string to match against + * + * + * fdt_node_check_compatible() returns 0 if the given node contains a + * 'compatible' property with the given string as one of its elements, + * it returns non-zero otherwise, or on error. + * + * returns: + * 0, if the node has a 'compatible' property listing the given string + * 1, if the node has a 'compatible' property, but it does not list + * the given string + * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property + * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_node_check_compatible(const void *fdt, int nodeoffset, + const char *compatible); + +/** + * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value + * @fdt: pointer to the device tree blob + * @startoffset: only find nodes after this offset + * @compatible: 'compatible' string to match against + * + * fdt_node_offset_by_compatible() returns the offset of the first + * node after startoffset, which has a 'compatible' property which + * lists the given compatible string; or if startoffset is -1, the + * very first such node in the tree. + * + * To iterate through all nodes matching the criterion, the following + * idiom can be used: + * offset = fdt_node_offset_by_compatible(fdt, -1, compatible); + * while (offset != -FDT_ERR_NOTFOUND) { + * // other code here + * offset = fdt_node_offset_by_compatible(fdt, offset, compatible); + * } + * + * Note the -1 in the first call to the function, if 0 is used here + * instead, the function will never locate the root node, even if it + * matches the criterion. + * + * returns: + * structure block offset of the located node (>= 0, >startoffset), + * on success + * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the + * tree after startoffset + * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, standard meanings + */ +int fdt_node_offset_by_compatible(const void *fdt, int startoffset, + const char *compatible); + +/**********************************************************************/ +/* Write-in-place functions */ +/**********************************************************************/ + +/** + * fdt_setprop_inplace - change a property's value, but not its size + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: pointer to data to replace the property value with + * @len: length of the property value + * + * fdt_setprop_inplace() replaces the value of a given property with + * the data in val, of length len. This function cannot change the + * size of a property, and so will only work if len is equal to the + * current length of the property. + * + * This function will alter only the bytes in the blob which contain + * the given property value, and will not alter or move any other part + * of the tree. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, if len is not equal to the property's current length + * -FDT_ERR_NOTFOUND, node does not have the named property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, + const void *val, int len); + +/** + * fdt_setprop_inplace_cell - change the value of a single-cell property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: cell (32-bit integer) value to replace the property with + * + * fdt_setprop_inplace_cell() replaces the value of a given property + * with the 32-bit integer cell value in val, converting val to + * big-endian if necessary. This function cannot change the size of a + * property, and so will only work if the property already exists and + * has length 4. + * + * This function will alter only the bytes in the blob which contain + * the given property value, and will not alter or move any other part + * of the tree. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, if the property's length is not equal to 4 + * -FDT_ERR_NOTFOUND, node does not have the named property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, + const char *name, uint32_t val) +{ + val = cpu_to_fdt32(val); + return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val)); +} + +/** + * fdt_nop_property - replace a property with nop tags + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to nop + * @name: name of the property to nop + * + * fdt_nop_property() will replace a given property's representation + * in the blob with FDT_NOP tags, effectively removing it from the + * tree. + * + * This function will alter only the bytes in the blob which contain + * the property, and will not alter or move any other part of the + * tree. + * + * returns: + * 0, on success + * -FDT_ERR_NOTFOUND, node does not have the named property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_nop_property(void *fdt, int nodeoffset, const char *name); + +/** + * fdt_nop_node - replace a node (subtree) with nop tags + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node to nop + * + * fdt_nop_node() will replace a given node's representation in the + * blob, including all its subnodes, if any, with FDT_NOP tags, + * effectively removing it from the tree. + * + * This function will alter only the bytes in the blob which contain + * the node and its properties and subnodes, and will not alter or + * move any other part of the tree. + * + * returns: + * 0, on success + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_nop_node(void *fdt, int nodeoffset); + +/**********************************************************************/ +/* Sequential write functions */ +/**********************************************************************/ + +int fdt_create(void *buf, int bufsize); +int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size); +int fdt_finish_reservemap(void *fdt); +int fdt_begin_node(void *fdt, const char *name); +int fdt_property(void *fdt, const char *name, const void *val, int len); +static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) +{ + val = cpu_to_fdt32(val); + return fdt_property(fdt, name, &val, sizeof(val)); +} +#define fdt_property_string(fdt, name, str) \ + fdt_property(fdt, name, str, strlen(str)+1) +int fdt_end_node(void *fdt); +int fdt_finish(void *fdt); + +/**********************************************************************/ +/* Read-write functions */ +/**********************************************************************/ + +int fdt_open_into(const void *fdt, void *buf, int bufsize); +int fdt_pack(void *fdt); + +/** + * fdt_add_mem_rsv - add one memory reserve map entry + * @fdt: pointer to the device tree blob + * @address, @size: 64-bit values (native endian) + * + * Adds a reserve map entry to the given blob reserving a region at + * address address of length size. + * + * This function will insert data into the reserve map and will + * therefore change the indexes of some entries in the table. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new reservation entry + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size); + +/** + * fdt_del_mem_rsv - remove a memory reserve map entry + * @fdt: pointer to the device tree blob + * @n: entry to remove + * + * fdt_del_mem_rsv() removes the n-th memory reserve map entry from + * the blob. + * + * This function will delete data from the reservation table and will + * therefore change the indexes of some entries in the table. + * + * returns: + * 0, on success + * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there + * are less than n+1 reserve map entries) + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_del_mem_rsv(void *fdt, int n); + +/** + * fdt_set_name - change the name of a given node + * @fdt: pointer to the device tree blob + * @nodeoffset: structure block offset of a node + * @name: name to give the node + * + * fdt_set_name() replaces the name (including unit address, if any) + * of the given node with the given string. NOTE: this function can't + * efficiently check if the new name is unique amongst the given + * node's siblings; results are undefined if this function is invoked + * with a name equal to one of the given node's siblings. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob + * to contain the new name + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, standard meanings + */ +int fdt_set_name(void *fdt, int nodeoffset, const char *name); + +/** + * fdt_setprop - create or change a property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: pointer to data to set the property value to + * @len: length of the property value + * + * fdt_setprop() sets the value of the named property in the given + * node to the given value and length, creating the property if it + * does not already exist. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_setprop(void *fdt, int nodeoffset, const char *name, + const void *val, int len); + +/** + * fdt_setprop_cell - set a property to a single cell value + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @val: 32-bit integer value for the property (native endian) + * + * fdt_setprop_cell() sets the value of the named property in the + * given node to the given cell value (converting to big-endian if + * necessary), or creates a new property with that value if it does + * not already exist. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, + uint32_t val) +{ + val = cpu_to_fdt32(val); + return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val)); +} + +/** + * fdt_setprop_string - set a property to a string value + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * @str: string value for the property + * + * fdt_setprop_string() sets the value of the named property in the + * given node to the given string value (using the length of the + * string to determine the new length of the property), or creates a + * new property with that value if it does not already exist. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +#define fdt_setprop_string(fdt, nodeoffset, name, str) \ + fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) + +/** + * fdt_delprop - delete a property + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to nop + * @name: name of the property to nop + * + * fdt_del_property() will delete the given property. + * + * This function will delete data from the blob, and will therefore + * change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOTFOUND, node does not have the named property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_delprop(void *fdt, int nodeoffset, const char *name); + +/** + * fdt_add_subnode_namelen - creates a new node based on substring + * @fdt: pointer to the device tree blob + * @parentoffset: structure block offset of a node + * @name: name of the subnode to locate + * @namelen: number of characters of name to consider + * + * Identical to fdt_add_subnode(), but use only the first namelen + * characters of name as the name of the new node. This is useful for + * creating subnodes based on a portion of a larger string, such as a + * full path. + */ +int fdt_add_subnode_namelen(void *fdt, int parentoffset, + const char *name, int namelen); + +/** + * fdt_add_subnode - creates a new node + * @fdt: pointer to the device tree blob + * @parentoffset: structure block offset of a node + * @name: name of the subnode to locate + * + * fdt_add_subnode() creates a new node as a subnode of the node at + * structure block offset parentoffset, with the given name (which + * should include the unit address, if any). + * + * This function will insert data into the blob, and will therefore + * change the offsets of some existing nodes. + + * returns: + * structure block offset of the created nodeequested subnode (>=0), on success + * -FDT_ERR_NOTFOUND, if the requested subnode does not exist + * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag + * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of + * the given name + * -FDT_ERR_NOSPACE, if there is insufficient free space in the + * blob to contain the new node + * -FDT_ERR_NOSPACE + * -FDT_ERR_BADLAYOUT + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings. + */ +int fdt_add_subnode(void *fdt, int parentoffset, const char *name); + +/** + * fdt_del_node - delete a node (subtree) + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node to nop + * + * fdt_del_node() will remove the given node, including all its + * subnodes if any, from the blob. + * + * This function will delete data from the blob, and will therefore + * change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_del_node(void *fdt, int nodeoffset); + +/**********************************************************************/ +/* Debugging / informational functions */ +/**********************************************************************/ + +const char *fdt_strerror(int errval); + +#endif /* _LIBFDT_H */ diff --git a/src/libs/libfdt/libfdt_env.h b/src/libs/libfdt/libfdt_env.h new file mode 100644 index 0000000000..449bf602da --- /dev/null +++ b/src/libs/libfdt/libfdt_env.h @@ -0,0 +1,23 @@ +#ifndef _LIBFDT_ENV_H +#define _LIBFDT_ENV_H + +#include +#include +#include + +#define _B(n) ((unsigned long long)((uint8_t *)&x)[n]) +static inline uint32_t fdt32_to_cpu(uint32_t x) +{ + return (_B(0) << 24) | (_B(1) << 16) | (_B(2) << 8) | _B(3); +} +#define cpu_to_fdt32(x) fdt32_to_cpu(x) + +static inline uint64_t fdt64_to_cpu(uint64_t x) +{ + return (_B(0) << 56) | (_B(1) << 48) | (_B(2) << 40) | (_B(3) << 32) + | (_B(4) << 24) | (_B(5) << 16) | (_B(6) << 8) | _B(7); +} +#define cpu_to_fdt64(x) fdt64_to_cpu(x) +#undef _B + +#endif /* _LIBFDT_ENV_H */ diff --git a/src/libs/libfdt/libfdt_internal.h b/src/libs/libfdt/libfdt_internal.h new file mode 100644 index 0000000000..381133ba81 --- /dev/null +++ b/src/libs/libfdt/libfdt_internal.h @@ -0,0 +1,95 @@ +#ifndef _LIBFDT_INTERNAL_H +#define _LIBFDT_INTERNAL_H +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * libfdt is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Alternatively, + * + * b) Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include + +#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) +#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) + +#define FDT_CHECK_HEADER(fdt) \ + { \ + int err; \ + if ((err = fdt_check_header(fdt)) != 0) \ + return err; \ + } + +int _fdt_check_node_offset(const void *fdt, int offset); +int _fdt_check_prop_offset(const void *fdt, int offset); +const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); +int _fdt_node_end_offset(void *fdt, int nodeoffset); + +static inline const void *_fdt_offset_ptr(const void *fdt, int offset) +{ + return (const char *)fdt + fdt_off_dt_struct(fdt) + offset; +} + +static inline void *_fdt_offset_ptr_w(void *fdt, int offset) +{ + return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset); +} + +static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n) +{ + const struct fdt_reserve_entry *rsv_table = + (const struct fdt_reserve_entry *) + ((const char *)fdt + fdt_off_mem_rsvmap(fdt)); + + return rsv_table + n; +} +static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n) +{ + return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n); +} + +#define FDT_SW_MAGIC (~FDT_MAGIC) + +#endif /* _LIBFDT_INTERNAL_H */ diff --git a/src/libs/libfdt/version.lds b/src/libs/libfdt/version.lds new file mode 100644 index 0000000000..3c3994e27f --- /dev/null +++ b/src/libs/libfdt/version.lds @@ -0,0 +1,54 @@ +LIBFDT_1.2 { + global: + fdt_next_node; + fdt_check_header; + fdt_move; + fdt_string; + fdt_num_mem_rsv; + fdt_get_mem_rsv; + fdt_subnode_offset_namelen; + fdt_subnode_offset; + fdt_path_offset; + fdt_get_name; + fdt_get_property_namelen; + fdt_get_property; + fdt_getprop_namelen; + fdt_getprop; + fdt_get_phandle; + fdt_get_alias_namelen; + fdt_get_alias; + fdt_get_path; + fdt_supernode_atdepth_offset; + fdt_node_depth; + fdt_parent_offset; + fdt_node_offset_by_prop_value; + fdt_node_offset_by_phandle; + fdt_node_check_compatible; + fdt_node_offset_by_compatible; + fdt_setprop_inplace; + fdt_nop_property; + fdt_nop_node; + fdt_create; + fdt_add_reservemap_entry; + fdt_finish_reservemap; + fdt_begin_node; + fdt_property; + fdt_end_node; + fdt_finish; + fdt_open_into; + fdt_pack; + fdt_add_mem_rsv; + fdt_del_mem_rsv; + fdt_set_name; + fdt_setprop; + fdt_delprop; + fdt_add_subnode_namelen; + fdt_add_subnode; + fdt_del_node; + fdt_strerror; + fdt_offset_ptr; + fdt_next_tag; + + local: + *; +}; From 48c009eb87f21941cd55b3c9bf5bee9205ad997c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Wed, 22 Aug 2012 20:18:47 +0200 Subject: [PATCH 003/137] libfdt: Move headers to headers/libs/libfdt --- {src => headers}/libs/libfdt/fdt.h | 0 {src => headers}/libs/libfdt/libfdt.h | 0 {src => headers}/libs/libfdt/libfdt_env.h | 0 {src => headers}/libs/libfdt/libfdt_internal.h | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename {src => headers}/libs/libfdt/fdt.h (100%) rename {src => headers}/libs/libfdt/libfdt.h (100%) rename {src => headers}/libs/libfdt/libfdt_env.h (100%) rename {src => headers}/libs/libfdt/libfdt_internal.h (100%) diff --git a/src/libs/libfdt/fdt.h b/headers/libs/libfdt/fdt.h similarity index 100% rename from src/libs/libfdt/fdt.h rename to headers/libs/libfdt/fdt.h diff --git a/src/libs/libfdt/libfdt.h b/headers/libs/libfdt/libfdt.h similarity index 100% rename from src/libs/libfdt/libfdt.h rename to headers/libs/libfdt/libfdt.h diff --git a/src/libs/libfdt/libfdt_env.h b/headers/libs/libfdt/libfdt_env.h similarity index 100% rename from src/libs/libfdt/libfdt_env.h rename to headers/libs/libfdt/libfdt_env.h diff --git a/src/libs/libfdt/libfdt_internal.h b/headers/libs/libfdt/libfdt_internal.h similarity index 100% rename from src/libs/libfdt/libfdt_internal.h rename to headers/libs/libfdt/libfdt_internal.h From 6955cba65be7cbcfc1a81701f4e8571fba47c5cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 24 Aug 2012 15:32:44 +0200 Subject: [PATCH 004/137] haiku_loader: add memchr to the list of imported libroot objects * libfdt uses memchr, so add this function from the libroot objects --- src/system/boot/Jamfile | 1 + 1 file changed, 1 insertion(+) diff --git a/src/system/boot/Jamfile b/src/system/boot/Jamfile index ad8d151046..0260857d8d 100644 --- a/src/system/boot/Jamfile +++ b/src/system/boot/Jamfile @@ -6,6 +6,7 @@ local librootFunctions = LocaleData.o qsort.o kernel_vsprintf.o + memchr.o memcmp.o memmove.o strdup.o From 78ea39c7d27cfcc1bf30ee25f54046192d3ff8f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 24 Aug 2012 15:48:02 +0200 Subject: [PATCH 005/137] U-Boot: compile and link to libfdt * For the sam460ex and likely some ARM boards we will try to boot using the passed FDT, as it's the recommended method now. --- src/system/boot/platform/u-boot/Jamfile | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/system/boot/platform/u-boot/Jamfile b/src/system/boot/platform/u-boot/Jamfile index dea0d99f23..68a754678e 100644 --- a/src/system/boot/platform/u-boot/Jamfile +++ b/src/system/boot/platform/u-boot/Jamfile @@ -22,6 +22,17 @@ UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) board $(TARGET_BOOT_BOAR SubDirC++Flags $(defines) -fno-rtti -g3 -O0 ; } +UseLibraryHeaders [ FDirName libfdt ] ; + +local libFDTSources = + fdt.c + fdt_ro.c + fdt_rw.c + fdt_strerror.c + fdt_sw.c + fdt_wip.c +; + # we fake NetBSD since we don't have an OS ID yet for uimage, # and we also fake a netbsd loader anyway. local uImageFakeOS = "netbsd" ; @@ -42,6 +53,7 @@ KernelMergeObject boot_platform_u-boot_common.o : video.cpp mmu.cpp $(genericPlatformSources) + $(libFDTSources) : -fno-pic @@ -235,6 +247,9 @@ Depends haiku-mmc-image : haiku-$(HAIKU_BOOT_BOARD).mmc ; SEARCH on [ FGristFiles $(genericPlatformSources) ] = [ FDirName $(HAIKU_TOP) src system boot platform generic ] ; +SEARCH on [ FGristFiles $(libFDTSources) ] + = [ FDirName $(HAIKU_TOP) src libs libfdt ] ; + # Tell the build system to where stage1.bin can be found, so it can be used # elsewhere. SEARCH on stage1.bin = $(SUBDIR) ; From 696526b2b8a21a95ca1bdc1bac2fb0f2279a25a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 24 Aug 2012 17:56:45 +0200 Subject: [PATCH 006/137] U-Boot: dump the passed FDT * add some helpers for Flattened Device Trees, for now a dump call * dump the passed FDT on startup for now --- src/system/boot/platform/u-boot/Jamfile | 1 + .../boot/platform/u-boot/fdt_support.cpp | 108 ++++++++++++++++++ src/system/boot/platform/u-boot/start.cpp | 7 +- 3 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 src/system/boot/platform/u-boot/fdt_support.cpp diff --git a/src/system/boot/platform/u-boot/Jamfile b/src/system/boot/platform/u-boot/Jamfile index 68a754678e..c395e5dca7 100644 --- a/src/system/boot/platform/u-boot/Jamfile +++ b/src/system/boot/platform/u-boot/Jamfile @@ -52,6 +52,7 @@ KernelMergeObject boot_platform_u-boot_common.o : uimage.cpp video.cpp mmu.cpp + fdt_support.cpp $(genericPlatformSources) $(libFDTSources) diff --git a/src/system/boot/platform/u-boot/fdt_support.cpp b/src/system/boot/platform/u-boot/fdt_support.cpp new file mode 100644 index 0000000000..3fba564ef0 --- /dev/null +++ b/src/system/boot/platform/u-boot/fdt_support.cpp @@ -0,0 +1,108 @@ +/* + * Copyright 2012, François Revol, revol@free.fr. + * Distributed under the terms of the MIT License. + */ + +#include +#include +#include +#include +#include + +extern "C" { +#include +#include +#include +}; + + +extern "C" void dump_fdt(const void *fdt); + +static const char *sTabTab = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; +#define DS "%.*s" +#define DA depth - 1, sTabTab + +#define FDT_DUMP_PROPS +//#define FDT_DUMP_PROP_VALUES + + +static void dump_hex(const char *data, int32 len, int depth) +{ + char str[128]; + char astr[32]; + char *p; + int l; + int i; + + for (i = 0; i < len; ) { + p = str; + l = sizeof(str); + for (; i < len && (p == str || (i % 16 != 0)); i++) { + snprintf(p, l - 1, "%02x ", data[i]); + l -= strlen(p); + p += strlen(p); + astr[i % 16] = isprint(data[i]) ? data[i] : '.'; + astr[i % 16] = isprint(data[i]) ? data[i] : '.'; + astr[(i % 16) + 1] = '\0'; + } + dprintf(DS" %-32.32s %s\n", DA, str, astr); + } +} + + +void dump_fdt(const void *fdt) +{ + uint32 *sizes; + int i, err, len; + int node = -1; + int depth = 0; + const struct fdt_property *property; + + dprintf("FDT @ %p:\n", fdt); + + if (!fdt) + return; + + err = fdt_check_header(fdt); + if (err) { + dprintf("fdt error: %s\n", fdt_strerror(err)); + return; + } + + dprintf("fdt_totalsize: %d\n", fdt_totalsize(fdt)); + dprintf("fdt_off_dt_struct: %d\n", fdt_off_dt_struct(fdt)); + dprintf("fdt_off_dt_strings: %d\n", fdt_off_dt_strings(fdt)); + dprintf("fdt_off_mem_rsvmap: %d\n", fdt_off_mem_rsvmap(fdt)); + dprintf("fdt_version: %d\n", fdt_version(fdt)); + dprintf("fdt_last_comp_version: %d\n", fdt_last_comp_version(fdt)); + dprintf("fdt_boot_cpuid_phys: %d\n", fdt_boot_cpuid_phys(fdt)); + dprintf("fdt_size_dt_strings: %d\n", fdt_size_dt_strings(fdt)); + dprintf("fdt_size_dt_struct: %d\n", fdt_size_dt_struct(fdt)); + + dprintf("fdt tree:\n"); + + while ((node = fdt_next_node(fdt, node, &depth)) >= 0) { + dprintf(DS"node at %d: '%s'\n", DA, node, + fdt_get_name(fdt, node, NULL)); +#ifdef FDT_DUMP_PROPS + int prop; + prop = fdt_first_property_offset(fdt, node); + while (prop >= 0) { + property = fdt_get_property_by_offset(fdt, prop, &len); + if (property == NULL) { + dprintf("getting prop at %d: %s\n", prop, fdt_strerror(len)); + break; + } + dprintf(DS" prop at %d: '%s', len %d\n", DA, prop, + fdt_string(fdt, fdt32_to_cpu(property->nameoff)), + fdt32_to_cpu(property->len)); +#ifdef FDT_DUMP_PROP_VALUES + dump_hex(property->data, fdt32_to_cpu(property->len), depth); +#endif + prop = fdt_next_property_offset(fdt, prop); + } +#endif + } +} + + diff --git a/src/system/boot/platform/u-boot/start.cpp b/src/system/boot/platform/u-boot/start.cpp index 9b87c906f4..a6ad586dd6 100644 --- a/src/system/boot/platform/u-boot/start.cpp +++ b/src/system/boot/platform/u-boot/start.cpp @@ -50,6 +50,7 @@ extern "C" int main(stage2_args *args); extern "C" void _start(void); extern "C" int start_raw(int argc, const char **argv); extern "C" void dump_uimage(struct image_header *image); +extern "C" void dump_fdt(const void *fdt); // declared in shell.S // those are initialized to NULL but not in the BSS @@ -186,11 +187,13 @@ start_raw(int argc, const char **argv) dprintf("argv[%d] @%lx = '%s'\n", i, (uint32)argv[i], argv[i]); dprintf("os: %d\n", (int)gUBootOS); dprintf("gd @ %p\n", gUBootGlobalData); - dprintf("gd->bd @ %p\n", gUBootGlobalData->bd); + if (gUBootGlobalData) + dprintf("gd->bd @ %p\n", gUBootGlobalData->bd); //dprintf("fb_base %p\n", (void*)gUBootGlobalData->fb_base); - dprintf("uimage @ %p\n", gUImage); if (gUImage) dump_uimage(gUImage); + if (gFDT) + dump_fdt(gFDT); } mmu_init(); From 513f67f193896ab464a1f32c4adce76306afa170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 24 Aug 2012 21:15:50 +0200 Subject: [PATCH 007/137] U-Boot: don't dump the FDT nodes by default * only dump some header infos from the FDT by default, as dumping the complete tree can get quite verbose. --- src/system/boot/platform/u-boot/fdt_support.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/system/boot/platform/u-boot/fdt_support.cpp b/src/system/boot/platform/u-boot/fdt_support.cpp index 3fba564ef0..cd7583dfd6 100644 --- a/src/system/boot/platform/u-boot/fdt_support.cpp +++ b/src/system/boot/platform/u-boot/fdt_support.cpp @@ -22,7 +22,8 @@ static const char *sTabTab = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; #define DS "%.*s" #define DA depth - 1, sTabTab -#define FDT_DUMP_PROPS +//#define FDT_DUMP_NODES +//#define FDT_DUMP_PROPS //#define FDT_DUMP_PROP_VALUES @@ -79,6 +80,7 @@ void dump_fdt(const void *fdt) dprintf("fdt_size_dt_strings: %d\n", fdt_size_dt_strings(fdt)); dprintf("fdt_size_dt_struct: %d\n", fdt_size_dt_struct(fdt)); +#ifdef FDT_DUMP_NODES dprintf("fdt tree:\n"); while ((node = fdt_next_node(fdt, node, &depth)) >= 0) { @@ -103,6 +105,7 @@ void dump_fdt(const void *fdt) } #endif } +#endif } From 74eeabe4a645ee37466160d824975cda4fe200b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 24 Aug 2012 21:20:09 +0200 Subject: [PATCH 008/137] U-Boot: initialize the debug UART using FDT hints when possible * we first try to find 'serial', 'serial0' or 'serial1' in /aliases * extract the required properties from the found node and use them * fallback to the hardcoded UART from the board definition header --- src/system/boot/platform/u-boot/serial.cpp | 97 +++++++++++++++++++++- src/system/boot/platform/u-boot/serial.h | 2 +- src/system/boot/platform/u-boot/start.cpp | 2 +- 3 files changed, 95 insertions(+), 6 deletions(-) diff --git a/src/system/boot/platform/u-boot/serial.cpp b/src/system/boot/platform/u-boot/serial.cpp index 12c6357d26..27bbb812a1 100644 --- a/src/system/boot/platform/u-boot/serial.cpp +++ b/src/system/boot/platform/u-boot/serial.cpp @@ -17,6 +17,12 @@ #include #include +extern "C" { +#include +#include +#include +}; + DebugUART* gUART; @@ -90,11 +96,94 @@ serial_cleanup(void) } -extern "C" void -serial_init(void) +static void +serial_init_fdt(const void *fdt) { - gUART = arch_get_uart_8250(BOARD_UART_DEBUG, BOARD_UART_CLOCK); - if (gUART == 0) + const char *name; + const char *type; + int node; + int len; + phys_addr_t regs; + int32 clock = 0; + int32 speed = 0; + const void *prop; + + if (fdt == NULL) + return; + + name = fdt_get_alias(fdt, "serial"); + if (name == NULL) + name = fdt_get_alias(fdt, "serial0"); + if (name == NULL) + name = fdt_get_alias(fdt, "serial1"); + // TODO: else use /chosen linux,stdout-path + if (name == NULL) + return; + + node = fdt_path_offset(fdt, name); + //dprintf("serial: using '%s', node %d\n", name, node); + if (node < 0) + return; + + type = (const char *)fdt_getprop(fdt, node, "device_type", &len); + //dprintf("serial: type: '%s'\n", type); + if (type == NULL || strcmp(type, "serial")) + return; + + // determine the MMIO address + // TODO: ppc640 use 64bit addressing, but U-Boot seems to map it below 4G, + // and the FDT is not very clear. libfdt is also getting 64bit addr support. + // so FIXME someday. + prop = fdt_getprop(fdt, node, "virtual-reg", &len); + if (prop && len == 4) { + regs = fdt32_to_cpu(*(uint32_t *)prop); + //dprintf("serial: virtual-reg 0x%08llx\n", (int64)regs); + } else { + prop = fdt_getprop(fdt, node, "reg", &len); + if (prop && len >= 4) { + regs = fdt32_to_cpu(*(uint32_t *)prop); + //dprintf("serial: reg 0x%08llx\n", (int64)regs); + } else + return; + } + + // get the UART clock rate + prop = fdt_getprop(fdt, node, "clock-frequency", &len); + if (prop && len == 4) { + clock = fdt32_to_cpu(*(uint32_t *)prop); + //dprintf("serial: clock %ld\n", clock); + } + + // get current speed (XXX: not yet passed over) + prop = fdt_getprop(fdt, node, "current-speed", &len); + if (prop && len == 4) { + speed = fdt32_to_cpu(*(uint32_t *)prop); + //dprintf("serial: speed %ld\n", speed); + } + + if (fdt_node_check_compatible(fdt, node, "ns16550a") == 1 + || fdt_node_check_compatible(fdt, node, "ns16550") == 1) { + gUART = arch_get_uart_8250(regs, clock); + //dprintf("serial: using 8250\n"); + return; + } + +} + + +extern "C" void +serial_init(const void *fdt) +{ + // first try with hints from the FDT + serial_init_fdt(fdt); + +#ifdef BOARD_UART_DEBUG + // fallback to hardcoded board UART + if (gUART == NULL) + gUART = arch_get_uart_8250(BOARD_UART_DEBUG, BOARD_UART_CLOCK); +#endif + + if (gUART == NULL) return; serial_enable(); diff --git a/src/system/boot/platform/u-boot/serial.h b/src/system/boot/platform/u-boot/serial.h index 5db0789eda..af09d8ce56 100644 --- a/src/system/boot/platform/u-boot/serial.h +++ b/src/system/boot/platform/u-boot/serial.h @@ -13,7 +13,7 @@ extern "C" { #endif -extern void serial_init(void); +extern void serial_init(const void *fdt); extern void serial_cleanup(void); extern void serial_puts(const char *string, size_t size); diff --git a/src/system/boot/platform/u-boot/start.cpp b/src/system/boot/platform/u-boot/start.cpp index a6ad586dd6..c379aa1ab4 100644 --- a/src/system/boot/platform/u-boot/start.cpp +++ b/src/system/boot/platform/u-boot/start.cpp @@ -167,7 +167,7 @@ start_raw(int argc, const char **argv) args.platform.boot_tgz_data = NULL; args.platform.boot_tgz_size = 0; - serial_init(); + serial_init(gFDT); console_init(); cpu_init(); From 60a40e4ff09114e1e53f65e8f3e93f159f2212a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 24 Aug 2012 23:04:16 +0200 Subject: [PATCH 009/137] U-Boot: fix hex dump in fdt support --- src/system/boot/platform/u-boot/fdt_support.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/boot/platform/u-boot/fdt_support.cpp b/src/system/boot/platform/u-boot/fdt_support.cpp index cd7583dfd6..96cec5411a 100644 --- a/src/system/boot/platform/u-boot/fdt_support.cpp +++ b/src/system/boot/platform/u-boot/fdt_support.cpp @@ -46,7 +46,7 @@ static void dump_hex(const char *data, int32 len, int depth) astr[i % 16] = isprint(data[i]) ? data[i] : '.'; astr[(i % 16) + 1] = '\0'; } - dprintf(DS" %-32.32s %s\n", DA, str, astr); + dprintf(DS" %-48.48s %s\n", DA, str, astr); } } From 80dfcc73119a3c34347db3709819c6a17d9883de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 25 Aug 2012 00:33:24 +0200 Subject: [PATCH 010/137] U-Boot: check for /chosen in the FDT for an initrd holding our tgz * since the FDT linux boot method doesn't pass the uimage, we can't use it to pass the kernel+driver tgz in a multi-file uimage. * instead we check for the linux initrd properties in the /chosen node. --- src/system/boot/platform/u-boot/start.cpp | 31 ++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/system/boot/platform/u-boot/start.cpp b/src/system/boot/platform/u-boot/start.cpp index c379aa1ab4..81b03bf03c 100644 --- a/src/system/boot/platform/u-boot/start.cpp +++ b/src/system/boot/platform/u-boot/start.cpp @@ -21,6 +21,12 @@ #include +extern "C" { +#include +#include +#include +}; + #define HEAP_SIZE (128 * 1024) @@ -171,12 +177,35 @@ start_raw(int argc, const char **argv) console_init(); cpu_init(); + // if we get passed an FDT, check /chosen for initrd + if (gFDT != NULL) { + int node = fdt_path_offset(gFDT, "/chosen"); + const void *prop; + int len; + phys_addr_t initrd_start = 0, initrd_end = 0; + + if (node >= 0) { + prop = fdt_getprop(gFDT, node, "linux,initrd-start", &len); + if (prop && len == 4) + initrd_start = fdt32_to_cpu(*(uint32_t *)prop); + prop = fdt_getprop(gFDT, node, "linux,initrd-end", &len); + if (prop && len == 4) + initrd_end = fdt32_to_cpu(*(uint32_t *)prop); + if (initrd_end > initrd_start) { + args.platform.boot_tgz_data = (void *)initrd_start; + args.platform.boot_tgz_size = initrd_end - initrd_start; + dprintf("Found boot tgz from FDT @ %p, %" B_PRIu32 " bytes\n", + args.platform.boot_tgz_data, args.platform.boot_tgz_size); + } + } + } + // if we get passed a uimage, try to find the second blob if (gUImage != NULL && image_multi_getimg(gUImage, 1, (uint32*)&args.platform.boot_tgz_data, &args.platform.boot_tgz_size)) { - dprintf("Found boot tgz @ %p, %" B_PRIu32 " bytes\n", + dprintf("Found boot tgz from uimage @ %p, %" B_PRIu32 " bytes\n", args.platform.boot_tgz_data, args.platform.boot_tgz_size); } From 5600cae48c32aa7c2fac2102775c72eff9ed937d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 22 Sep 2012 03:39:19 +0200 Subject: [PATCH 011/137] Add arch_framebuffer.h for ppc * should fix the build --- src/system/boot/arch/ppc/arch_framebuffer.h | 51 +++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/system/boot/arch/ppc/arch_framebuffer.h diff --git a/src/system/boot/arch/ppc/arch_framebuffer.h b/src/system/boot/arch/ppc/arch_framebuffer.h new file mode 100644 index 0000000000..6057d0f7ac --- /dev/null +++ b/src/system/boot/arch/ppc/arch_framebuffer.h @@ -0,0 +1,51 @@ +/* + * Copyright 2011-2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck IV, kallisti5@unixzen.com + */ +#ifndef _ARCH_FRAMEBUFFER_H +#define _ARCH_FRAMEBUFFER_H + + +#include +#include + + +#define TRACE_VIDEO +#ifdef TRACE_VIDEO +# define TRACE(x...) dprintf(x) +# define CALLED() dprintf("%s()\n", __func__); +#else +# define TRACE(x...) ; +# define CALLED() ; +#endif +#define ERROR(x...) dprintf(x) + + +class ArchFramebuffer { +public: + ArchFramebuffer(addr_t base) + : + fBase(base) {}; + ~ArchFramebuffer() {}; + + virtual status_t Init() { return B_OK; }; + virtual status_t Probe() { return B_OK; }; + virtual status_t SetDefaultMode() { return B_OK; }; + virtual status_t SetVideoMode(int width, int height, int depth) + { return B_OK; }; + + virtual addr_t Base() { return fBase; }; + +protected: + addr_t fBase; +private: + int fCurrentWidth; + int fCurrentHeight; + int fCurrentDepth; +}; + + +#endif /* _ARCH_FRAMEBUFFER_H */ From 79290de84544370ef292ad9a69393b5a98fdfded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 22 Sep 2012 19:23:31 +0200 Subject: [PATCH 012/137] U-Boot: HACK: Fix linking the kernel * For now let's include the same fields in platform_kernel_args than in the OF version. * This allows linking the kernel. Later on we should allow supporting more than a single boot platform, to have a single kernel per arch. --- .../kernel/boot/platform/u-boot/platform_kernel_args.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/headers/private/kernel/boot/platform/u-boot/platform_kernel_args.h b/headers/private/kernel/boot/platform/u-boot/platform_kernel_args.h index 6e898ba11e..ae65dbc361 100644 --- a/headers/private/kernel/boot/platform/u-boot/platform_kernel_args.h +++ b/headers/private/kernel/boot/platform/u-boot/platform_kernel_args.h @@ -17,6 +17,12 @@ typedef struct { + // XXX: HACK: must match the OF platform args + // FIXME: use a union instead? + void *openfirmware_entry; + char rtc_path[128]; + + // TODO: add FDT char dummy; } platform_kernel_args; From daf2a95ef7e76b85df81e9f71351ad1b4066a209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 22 Sep 2012 19:55:02 +0200 Subject: [PATCH 013/137] PPC: Add a PPC_PLATFORM_U_BOOT platform type * the PPC kernel will have to support both OF and U-Boot soon. --- headers/private/kernel/arch/ppc/arch_platform.h | 1 + 1 file changed, 1 insertion(+) diff --git a/headers/private/kernel/arch/ppc/arch_platform.h b/headers/private/kernel/arch/ppc/arch_platform.h index d4550cda52..30d5ff132a 100644 --- a/headers/private/kernel/arch/ppc/arch_platform.h +++ b/headers/private/kernel/arch/ppc/arch_platform.h @@ -11,6 +11,7 @@ struct real_time_data; enum ppc_platform_type { PPC_PLATFORM_OPEN_FIRMWARE = 0, + PPC_PLATFORM_U_BOOT }; namespace BPrivate { From 9a713d9417fb71a8679d792eb174b3cee59dbda7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 22 Sep 2012 20:45:25 +0200 Subject: [PATCH 014/137] U-Boot: PPC: stub out OF calls * For now this allows linking the kernel and the pci bus manager. * Could later on be turned into a wrapper to FDT methods since the concepts are similar. --- src/system/kernel/platform/u-boot/Jamfile | 1 + .../kernel/platform/u-boot/openfirmware.cpp | 224 ++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 src/system/kernel/platform/u-boot/openfirmware.cpp diff --git a/src/system/kernel/platform/u-boot/Jamfile b/src/system/kernel/platform/u-boot/Jamfile index d29857ba59..d1845da417 100644 --- a/src/system/kernel/platform/u-boot/Jamfile +++ b/src/system/kernel/platform/u-boot/Jamfile @@ -5,4 +5,5 @@ SubDirC++Flags $(TARGET_KERNEL_PIC_CCFLAGS) ; KernelMergeObject kernel_platform_u-boot.o : platform.cpp + openfirmware.cpp ; diff --git a/src/system/kernel/platform/u-boot/openfirmware.cpp b/src/system/kernel/platform/u-boot/openfirmware.cpp new file mode 100644 index 0000000000..5ee024cd1b --- /dev/null +++ b/src/system/kernel/platform/u-boot/openfirmware.cpp @@ -0,0 +1,224 @@ +/* + * Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ + +#include +#include + +#include + + +// FIXME: HACK: until we support multiple platforms at once in the kernel. + +int gChosen; + + +status_t +of_init(int (*openFirmwareEntry)(void *)) +{ + gChosen = of_finddevice("/chosen"); + if (gChosen == OF_FAILED) + return B_ERROR; + + return B_OK; +} + + +int +of_call_client_function(const char *method, int numArgs, int numReturns, ...) +{ + return OF_FAILED; +} + + +int +of_interpret(const char *command, int numArgs, int numReturns, ...) +{ + return OF_FAILED; +} + + +int +of_call_method(int handle, const char *method, int numArgs, int numReturns, ...) +{ + return OF_FAILED; +} + + +int +of_finddevice(const char *device) +{ + return OF_FAILED; +} + + +status_t +of_get_next_device(int *_cookie, int root, const char *type, char *path, + size_t pathSize) +{ + return B_ERROR; +} + + +/** Returns the first child of the given node + */ + +int +of_child(int node) +{ + return OF_FAILED; +} + + +/** Returns the next sibling of the given node + */ + +int +of_peer(int node) +{ + return OF_FAILED; +} + + +/** Returns the parent of the given node + */ + +int +of_parent(int node) +{ + return OF_FAILED; +} + + +int +of_instance_to_path(int instance, char *pathBuffer, int bufferSize) +{ + return OF_FAILED; +} + + +int +of_instance_to_package(int instance) +{ + return OF_FAILED; +} + + +int +of_getprop(int package, const char *property, void *buffer, int bufferSize) +{ + return OF_FAILED; +} + + +int +of_setprop(int package, const char *property, const void *buffer, int bufferSize) +{ + return OF_FAILED; +} + + +int +of_getproplen(int package, const char *property) +{ + return OF_FAILED; +} + + +int +of_nextprop(int package, const char *previousProperty, char *nextProperty) +{ + return OF_FAILED; +} + + +int +of_package_to_path(int package, char *pathBuffer, int bufferSize) +{ + return OF_FAILED; +} + + +// I/O functions + + +int +of_open(const char *nodeName) +{ + return OF_FAILED; +} + + +void +of_close(int handle) +{ +} + + +int +of_read(int handle, void *buffer, int bufferSize) +{ + return OF_FAILED; +} + + +int +of_write(int handle, const void *buffer, int bufferSize) +{ + return OF_FAILED; +} + + +int +of_seek(int handle, long long pos) +{ + return OF_FAILED; +} + + +// memory functions + + +int +of_release(void *virtualAddress, int size) +{ + return OF_FAILED; +} + + +void * +of_claim(void *virtualAddress, int size, int align) +{ + return NULL; +} + + +// misc functions + + +/** tests if the given service is missing + */ + +int +of_test(const char *service) +{ + return OF_FAILED; +} + + +/** Returns the millisecond counter + */ + +int +of_milliseconds(void) +{ + return OF_FAILED; +} + + +void +of_exit(void) +{ +} + From f81233185780da21480331028eed220022e2d0b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 22 Sep 2012 22:10:02 +0200 Subject: [PATCH 015/137] PPC: Add a platform field to the arch_kernel_args * We need to know which platform we are booted from --- headers/private/kernel/arch/ppc/arch_kernel_args.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/headers/private/kernel/arch/ppc/arch_kernel_args.h b/headers/private/kernel/arch/ppc/arch_kernel_args.h index 7780bfe7c9..26370d0d30 100644 --- a/headers/private/kernel/arch/ppc/arch_kernel_args.h +++ b/headers/private/kernel/arch/ppc/arch_kernel_args.h @@ -29,6 +29,9 @@ typedef struct { // to the Open Firmware. uint32 num_virtual_ranges_to_keep; addr_range virtual_ranges_to_keep[MAX_VIRTUAL_RANGES_TO_KEEP]; + + // platform type we booted from + int platform; } arch_kernel_args; #endif /* KERNEL_ARCH_PPC_KERNEL_ARGS_H */ From 0e5f9797201b006636c70a95a9664c19c85a24d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 22 Sep 2012 22:12:56 +0200 Subject: [PATCH 016/137] PPC: Add a stub PPCUBoot platform class * use the platform field in arch_kernel_args to determine which platform to instanciate --- src/system/kernel/arch/ppc/arch_platform.cpp | 126 ++++++++++++++++++- 1 file changed, 123 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/arch/ppc/arch_platform.cpp b/src/system/kernel/arch/ppc/arch_platform.cpp index 2e2d95ffd0..35e92adb0f 100644 --- a/src/system/kernel/arch/ppc/arch_platform.cpp +++ b/src/system/kernel/arch/ppc/arch_platform.cpp @@ -225,18 +225,138 @@ PPCOpenFirmware::ShutDown(bool reboot) } +// #pragma mark - U-Boot + FDT + + +namespace BPrivate { + +class PPCUBoot : public PPCPlatform { +public: + PPCUBoot(); + virtual ~PPCUBoot(); + + virtual status_t Init(struct kernel_args *kernelArgs); + virtual status_t InitSerialDebug(struct kernel_args *kernelArgs); + virtual status_t InitPostVM(struct kernel_args *kernelArgs); + virtual status_t InitRTC(struct kernel_args *kernelArgs, + struct real_time_data *data); + + virtual char SerialDebugGetChar(); + virtual void SerialDebugPutChar(char c); + + virtual void SetHardwareRTC(uint32 seconds); + virtual uint32 GetHardwareRTC(); + + virtual void ShutDown(bool reboot); + +private: + int fInput; + int fOutput; + int fRTC; +}; + +} // namespace BPrivate + +using BPrivate::PPCUBoot; + + +// constructor +PPCUBoot::PPCUBoot() + : PPCPlatform(PPC_PLATFORM_U_BOOT), + fInput(-1), + fOutput(-1), + fRTC(-1) +{ +} + +// destructor +PPCUBoot::~PPCUBoot() +{ +} + +// Init +status_t +PPCUBoot::Init(struct kernel_args *kernelArgs) +{ + return B_ERROR; +} + +// InitSerialDebug +status_t +PPCUBoot::InitSerialDebug(struct kernel_args *kernelArgs) +{ + return B_ERROR; +} + +// InitPostVM +status_t +PPCUBoot::InitPostVM(struct kernel_args *kernelArgs) +{ + return B_ERROR; +} + +// InitRTC +status_t +PPCUBoot::InitRTC(struct kernel_args *kernelArgs, + struct real_time_data *data) +{ + return B_ERROR; +} + +// DebugSerialGetChar +char +PPCUBoot::SerialDebugGetChar() +{ + return 0; +} + +// DebugSerialPutChar +void +PPCUBoot::SerialDebugPutChar(char c) +{ +} + +// SetHardwareRTC +void +PPCUBoot::SetHardwareRTC(uint32 seconds) +{ +} + +// GetHardwareRTC +uint32 +PPCUBoot::GetHardwareRTC() +{ + return 0; +} + +// ShutDown +void +PPCUBoot::ShutDown(bool reboot) +{ +} + + // # pragma mark - +#define PLATFORM_BUFFER_SIZE MAX(sizeof(PPCOpenFirmware),sizeof(PPCUBoot)) // static buffer for constructing the actual PPCPlatform -static char *sPPCPlatformBuffer[sizeof(PPCOpenFirmware)]; +static char *sPPCPlatformBuffer[PLATFORM_BUFFER_SIZE]; status_t arch_platform_init(struct kernel_args *kernelArgs) { // only OpenFirmware supported for now - if (true) - sPPCPlatform = new(sPPCPlatformBuffer) PPCOpenFirmware; + switch (kernelArgs->arch_args.platform) { + case PPC_PLATFORM_OPEN_FIRMWARE: + sPPCPlatform = new(sPPCPlatformBuffer) PPCOpenFirmware; + break; + case PPC_PLATFORM_U_BOOT: + sPPCPlatform = new(sPPCPlatformBuffer) PPCUBoot; + break; + default: + return B_ERROR; + } return sPPCPlatform->Init(kernelArgs); } From 3b8d5dc824d3db9e48fe91827296ebf1a397242f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 22 Sep 2012 22:23:00 +0200 Subject: [PATCH 017/137] PPC: Add stub u-boot version of the PCI controller. * Add a switch on the platform type --- .../kernel/bus_managers/pci/arch/ppc/Jamfile | 4 ++++ .../pci/arch/ppc/pci_controller.cpp | 8 +++++-- .../pci/arch/ppc/u-boot/pci_u-boot.cpp | 24 +++++++++++++++++++ .../pci/arch/ppc/u-boot/pci_u-boot.h | 13 ++++++++++ 4 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.cpp create mode 100644 src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.h diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/Jamfile b/src/add-ons/kernel/bus_managers/pci/arch/ppc/Jamfile index 99e04130f6..2f81efb0e5 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/Jamfile +++ b/src/add-ons/kernel/bus_managers/pci/arch/ppc/Jamfile @@ -5,6 +5,7 @@ UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ] [ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) openfirmware ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) u-boot ] ; KernelStaticLibrary pci_arch_bus_manager : pci_controller.cpp @@ -14,4 +15,7 @@ KernelStaticLibrary pci_arch_bus_manager : pci_openfirmware.cpp uninorth.cpp grackle.cpp + + # U-Boot + pci_u-boot.cpp ; diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/pci_controller.cpp b/src/add-ons/kernel/bus_managers/pci/arch/ppc/pci_controller.cpp index 8c0a6cd075..50caa2b6ff 100644 --- a/src/add-ons/kernel/bus_managers/pci/arch/ppc/pci_controller.cpp +++ b/src/add-ons/kernel/bus_managers/pci/arch/ppc/pci_controller.cpp @@ -11,6 +11,7 @@ #include "pci_private.h" #include "openfirmware/pci_openfirmware.h" +#include "u-boot/pci_u-boot.h" status_t @@ -19,9 +20,12 @@ pci_controller_init(void) switch (PPCPlatform::Default()->PlatformType()) { case PPC_PLATFORM_OPEN_FIRMWARE: return ppc_openfirmware_pci_controller_init(); - break; + case PPC_PLATFORM_U_BOOT: + return ppc_uboot_pci_controller_init(); + default: + panic("pci: unknown platform"); } - return B_OK; + return B_ERROR; } diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.cpp b/src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.cpp new file mode 100644 index 0000000000..0f00491f32 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.cpp @@ -0,0 +1,24 @@ +/* + * Copyright 2006, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "pci_u-boot.h" + +#include +#include + +#include + +//#include +//#include +//#include + + +status_t +ppc_uboot_pci_controller_init(void) +{ + return B_ERROR; +} + + diff --git a/src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.h b/src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.h new file mode 100644 index 0000000000..07a6a71916 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/pci/arch/ppc/u-boot/pci_u-boot.h @@ -0,0 +1,13 @@ +/* + * Copyright 2012, François Revol . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#ifndef PCI_BUS_MANAGER_PPC_U_BOOT_H +#define PCI_BUS_MANAGER_PPC_U_BOOT_H + +#include + +status_t ppc_uboot_pci_controller_init(void); + +#endif // PCI_BUS_MANAGER_PPC_U_BOOT_H From ca6bf83ff90b352c84742d268f8bd8f39d37cbb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 23 Sep 2012 02:59:40 +0200 Subject: [PATCH 018/137] Fix warnings --- .../boot/platform/u-boot/fdt_support.cpp | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/system/boot/platform/u-boot/fdt_support.cpp b/src/system/boot/platform/u-boot/fdt_support.cpp index 96cec5411a..d0ac350ae8 100644 --- a/src/system/boot/platform/u-boot/fdt_support.cpp +++ b/src/system/boot/platform/u-boot/fdt_support.cpp @@ -18,15 +18,19 @@ extern "C" { extern "C" void dump_fdt(const void *fdt); -static const char *sTabTab = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; -#define DS "%.*s" -#define DA depth - 1, sTabTab - //#define FDT_DUMP_NODES //#define FDT_DUMP_PROPS //#define FDT_DUMP_PROP_VALUES +#ifdef FDT_DUMP_NODES +static const char *sTabTab = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; +#define DS "%.*s" +#define DA depth - 1, sTabTab +#endif + + +#ifdef FDT_DUMP_PROP_VALUES static void dump_hex(const char *data, int32 len, int depth) { char str[128]; @@ -49,15 +53,12 @@ static void dump_hex(const char *data, int32 len, int depth) dprintf(DS" %-48.48s %s\n", DA, str, astr); } } +#endif void dump_fdt(const void *fdt) { - uint32 *sizes; - int i, err, len; - int node = -1; - int depth = 0; - const struct fdt_property *property; + int err; dprintf("FDT @ %p:\n", fdt); @@ -83,11 +84,14 @@ void dump_fdt(const void *fdt) #ifdef FDT_DUMP_NODES dprintf("fdt tree:\n"); + int node = -1; + int depth = 0; while ((node = fdt_next_node(fdt, node, &depth)) >= 0) { dprintf(DS"node at %d: '%s'\n", DA, node, fdt_get_name(fdt, node, NULL)); #ifdef FDT_DUMP_PROPS - int prop; + int prop, len; + const struct fdt_property *property; prop = fdt_first_property_offset(fdt, node); while (prop >= 0) { property = fdt_get_property_by_offset(fdt, prop, &len); From 5dfa763cb1f94ed1c4b5ec1f039081dbf66974a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 6 Nov 2012 16:34:01 +0100 Subject: [PATCH 019/137] OF: Make sure the of_region templatized struct is packed At least when building for sam460ex, it ended up being 16bytes large... --- headers/private/kernel/platform/openfirmware/openfirmware.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/headers/private/kernel/platform/openfirmware/openfirmware.h b/headers/private/kernel/platform/openfirmware/openfirmware.h index e5ebf77ddd..7c82079c6b 100644 --- a/headers/private/kernel/platform/openfirmware/openfirmware.h +++ b/headers/private/kernel/platform/openfirmware/openfirmware.h @@ -20,7 +20,7 @@ template struct of_region { AddressType base; uint32 size; -}; +} _PACKED; struct of_arguments { const char *name; From f24f590392a910b547e2463843d34b33d4fdb958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 6 Nov 2012 16:41:36 +0100 Subject: [PATCH 020/137] U-Boot: implement part of the OpenFirmware wrapper We'll see later on if it's really useful to keep it around. --- src/system/boot/platform/u-boot/Jamfile | 4 + src/system/boot/platform/u-boot/start.cpp | 4 + src/system/kernel/platform/u-boot/Jamfile | 2 + .../kernel/platform/u-boot/openfirmware.cpp | 79 ++++++++++++++++++- 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/src/system/boot/platform/u-boot/Jamfile b/src/system/boot/platform/u-boot/Jamfile index 029fd3da54..7641bea93c 100644 --- a/src/system/boot/platform/u-boot/Jamfile +++ b/src/system/boot/platform/u-boot/Jamfile @@ -52,6 +52,7 @@ KernelMergeObject boot_platform_u-boot_common.o : uimage.cpp video.cpp fdt_support.cpp + openfirmware.cpp $(genericPlatformSources) $(libFDTSources) @@ -247,6 +248,9 @@ Depends haiku-mmc-image : haiku-$(HAIKU_BOOT_BOARD).mmc ; SEARCH on [ FGristFiles $(genericPlatformSources) ] = [ FDirName $(HAIKU_TOP) src system boot platform generic ] ; +SEARCH on [ FGristFiles openfirmware.cpp ] + = [ FDirName $(HAIKU_TOP) src system kernel platform u-boot ] ; + SEARCH on [ FGristFiles $(libFDTSources) ] = [ FDirName $(HAIKU_TOP) src libs libfdt ] ; diff --git a/src/system/boot/platform/u-boot/start.cpp b/src/system/boot/platform/u-boot/start.cpp index 81b03bf03c..1f51487af5 100644 --- a/src/system/boot/platform/u-boot/start.cpp +++ b/src/system/boot/platform/u-boot/start.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -198,6 +199,9 @@ start_raw(int argc, const char **argv) args.platform.boot_tgz_data, args.platform.boot_tgz_size); } } + + // also initialize the OpenFirmware wrapper + of_init(NULL); } // if we get passed a uimage, try to find the second blob diff --git a/src/system/kernel/platform/u-boot/Jamfile b/src/system/kernel/platform/u-boot/Jamfile index d1845da417..b9604505c7 100644 --- a/src/system/kernel/platform/u-boot/Jamfile +++ b/src/system/kernel/platform/u-boot/Jamfile @@ -3,6 +3,8 @@ SubDir HAIKU_TOP src system kernel platform u-boot ; SubDirCcFlags $(TARGET_KERNEL_PIC_CCFLAGS) ; SubDirC++Flags $(TARGET_KERNEL_PIC_CCFLAGS) ; +UseLibraryHeaders [ FDirName libfdt ] ; + KernelMergeObject kernel_platform_u-boot.o : platform.cpp openfirmware.cpp diff --git a/src/system/kernel/platform/u-boot/openfirmware.cpp b/src/system/kernel/platform/u-boot/openfirmware.cpp index 5ee024cd1b..557f4e5bc2 100644 --- a/src/system/kernel/platform/u-boot/openfirmware.cpp +++ b/src/system/kernel/platform/u-boot/openfirmware.cpp @@ -7,13 +7,45 @@ #include #include +#include + +extern "C" { +#include +#include +#include +}; // FIXME: HACK: until we support multiple platforms at once in the kernel. +extern void *gFDT; int gChosen; +static int fdt2of(int err) +{ + if (err >= 0) + return err; + switch (err) { + case -FDT_ERR_NOTFOUND: + case -FDT_ERR_EXISTS: + case -FDT_ERR_NOSPACE: + case -FDT_ERR_BADOFFSET: + case -FDT_ERR_BADPATH: + case -FDT_ERR_BADPHANDLE: + case -FDT_ERR_BADSTATE: + case -FDT_ERR_TRUNCATED: + case -FDT_ERR_BADMAGIC: + case -FDT_ERR_BADVERSION: + case -FDT_ERR_BADSTRUCTURE: + case -FDT_ERR_BADLAYOUT: + case -FDT_ERR_INTERNAL: + default: + return OF_FAILED; + } +} + + status_t of_init(int (*openFirmwareEntry)(void *)) { @@ -49,7 +81,18 @@ of_call_method(int handle, const char *method, int numArgs, int numReturns, ...) int of_finddevice(const char *device) { - return OF_FAILED; + const char *name = device; + int node; + + if (device == NULL) + return OF_FAILED; + + if (device[0] != '/' && fdt_get_alias(gFDT, device)) + name = fdt_get_alias(gFDT, device); + + node = fdt_path_offset(gFDT, name); +dprintf("of_finddevice('%s') name='%s' node=%d ret=%d\n", device, name, node, fdt2of(node)); + return fdt2of(node); } @@ -108,7 +151,13 @@ of_instance_to_package(int instance) int of_getprop(int package, const char *property, void *buffer, int bufferSize) { - return OF_FAILED; +int oldSize = bufferSize; + const void *p = fdt_getprop(gFDT, package, property, &bufferSize); +dprintf("of_getprop(%d, '%s', , %d) =%p sz=%d ret=%d\n", package, property, oldSize, p, bufferSize, fdt2of(bufferSize)); + if (p == NULL) + return fdt2of(bufferSize); + memcpy(buffer, p, bufferSize); + return bufferSize; } @@ -140,6 +189,32 @@ of_package_to_path(int package, char *pathBuffer, int bufferSize) } +/** given the package provided, get the number of cells ++ in the reg property ++ */ + +int32 +of_address_cells(int package) { + uint32 address_cells; + if (of_getprop(package, "#address-cells", + &address_cells, sizeof(address_cells)) == OF_FAILED) + return OF_FAILED; + + return address_cells; +} + + +int32 +of_size_cells(int package) { + uint32 size_cells; + if (of_getprop(package, "#size-cells", + &size_cells, sizeof(size_cells)) == OF_FAILED) + return OF_FAILED; + + return size_cells; +} + + // I/O functions From 3b4ba8d6074e8b91786ae237d569a859129a7a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 6 Nov 2012 16:45:39 +0100 Subject: [PATCH 021/137] U-Boot: PPC: Copy the memory sizing code from OF Just an exercise to see how well the OF wrapper works. Had to adjust cause the FDT I had had /memory node, but no memory prop on /chosen. --- .../platform/u-boot/arch/ppc/arch_mmu.cpp | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/src/system/boot/platform/u-boot/arch/ppc/arch_mmu.cpp b/src/system/boot/platform/u-boot/arch/ppc/arch_mmu.cpp index bab74229fd..640cf894b1 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/arch_mmu.cpp +++ b/src/system/boot/platform/u-boot/arch/ppc/arch_mmu.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef __ARM__ #include #endif @@ -25,6 +26,8 @@ #include +int32 of_address_cells(int package); +int32 of_size_cells(int package); //#define TRACE_MMU #ifdef TRACE_MMU @@ -595,11 +598,119 @@ mmu_init_for_kernel(void) } +//XXX:move this +static status_t +find_physical_memory_ranges(size_t &total) +{ + int memory = -1; + int package; + dprintf("checking for memory...\n"); + if (of_getprop(gChosen, "memory", &memory, sizeof(int)) == OF_FAILED) + package = of_finddevice("/memory"); + else + package = of_instance_to_package(memory); + if (package == OF_FAILED) + return B_ERROR; + + total = 0; + + // Memory base addresses are provided in 32 or 64 bit flavors + // #address-cells and #size-cells matches the number of 32-bit 'cells' + // representing the length of the base address and size fields + int root = of_finddevice("/"); + int32 regAddressCells = of_address_cells(root); + int32 regSizeCells = of_size_cells(root); + if (regAddressCells == OF_FAILED || regSizeCells == OF_FAILED) { + dprintf("finding base/size length counts failed, assume 32-bit.\n"); + regAddressCells = 1; + regSizeCells = 1; + } + + // NOTE : Size Cells of 2 is possible in theory... but I haven't seen it yet. + if (regAddressCells > 2 || regSizeCells > 1) { + panic("%s: Unsupported OpenFirmware cell count detected.\n" + "Address Cells: %" B_PRId32 "; Size Cells: %" B_PRId32 + " (CPU > 64bit?).\n", __func__, regAddressCells, regSizeCells); + return B_ERROR; + } + + // On 64-bit PowerPC systems (G5), our mem base range address is larger + if (regAddressCells == 2) { + struct of_region regions[64]; + int count = of_getprop(package, "reg", regions, sizeof(regions)); + if (count == OF_FAILED) + count = of_getprop(memory, "reg", regions, sizeof(regions)); + if (count == OF_FAILED) + return B_ERROR; + count /= sizeof(regions[0]); + + for (int32 i = 0; i < count; i++) { + if (regions[i].size <= 0) { + dprintf("%ld: empty region\n", i); + continue; + } + dprintf("%" B_PRIu32 ": base = %" B_PRIu64 "," + "size = %" B_PRIu32 "\n", i, regions[i].base, regions[i].size); + + total += regions[i].size; + + if (insert_physical_memory_range((addr_t)regions[i].base, + regions[i].size) != B_OK) { + dprintf("cannot map physical memory range " + "(num ranges = %" B_PRIu32 ")!\n", + gKernelArgs.num_physical_memory_ranges); + return B_ERROR; + } + } + return B_OK; + } + + // Otherwise, normal 32-bit PowerPC G3 or G4 have a smaller 32-bit one + struct of_region regions[64]; + int count = of_getprop(package, "reg", regions, sizeof(regions)); + if (count == OF_FAILED) + count = of_getprop(memory, "reg", regions, sizeof(regions)); + if (count == OF_FAILED) + return B_ERROR; + count /= sizeof(regions[0]); + + for (int32 i = 0; i < count; i++) { + if (regions[i].size <= 0) { + dprintf("%ld: empty region\n", i); + continue; + } + dprintf("%" B_PRIu32 ": base = %" B_PRIu32 "," + "size = %" B_PRIu32 "\n", i, regions[i].base, regions[i].size); + + total += regions[i].size; + + if (insert_physical_memory_range((addr_t)regions[i].base, + regions[i].size) != B_OK) { + dprintf("cannot map physical memory range " + "(num ranges = %" B_PRIu32 ")!\n", + gKernelArgs.num_physical_memory_ranges); + return B_ERROR; + } + } + + return B_OK; +} + + extern "C" void mmu_init(void) { TRACE(("mmu_init\n")); + // get map of physical memory (fill in kernel_args structure) + + size_t total; + if (find_physical_memory_ranges(total) != B_OK) { + dprintf("Error: could not find physical memory ranges!\n"); + return /*B_ERROR*/; + } + dprintf("total physical memory = %" B_PRId32 "MB\n", total / (1024 * 1024)); + #ifdef __ARM__ mmu_write_C1(mmu_read_C1() & ~((1<<29)|(1<<28)|(1<<0))); // access flag disabled, TEX remap disabled, mmu disabled From 2d014a28863f95a905daaa1f75aa9637565dd16a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 6 Nov 2012 19:43:12 +0100 Subject: [PATCH 022/137] U-Boot: Fix linking the kernel by adding FDT support Add FDT support to the kernel, move fdt_support.cpp and declare gFDT there for the kernel. --- src/system/boot/platform/u-boot/Jamfile | 2 +- src/system/kernel/platform/u-boot/Jamfile | 15 +++++++++++++++ .../platform/u-boot/fdt_support.cpp | 4 ++++ 3 files changed, 20 insertions(+), 1 deletion(-) rename src/system/{boot => kernel}/platform/u-boot/fdt_support.cpp (96%) diff --git a/src/system/boot/platform/u-boot/Jamfile b/src/system/boot/platform/u-boot/Jamfile index 7641bea93c..a2cea4405b 100644 --- a/src/system/boot/platform/u-boot/Jamfile +++ b/src/system/boot/platform/u-boot/Jamfile @@ -248,7 +248,7 @@ Depends haiku-mmc-image : haiku-$(HAIKU_BOOT_BOARD).mmc ; SEARCH on [ FGristFiles $(genericPlatformSources) ] = [ FDirName $(HAIKU_TOP) src system boot platform generic ] ; -SEARCH on [ FGristFiles openfirmware.cpp ] +SEARCH on [ FGristFiles openfirmware.cpp fdt_support.cpp ] = [ FDirName $(HAIKU_TOP) src system kernel platform u-boot ] ; SEARCH on [ FGristFiles $(libFDTSources) ] diff --git a/src/system/kernel/platform/u-boot/Jamfile b/src/system/kernel/platform/u-boot/Jamfile index b9604505c7..dbadd8cbcb 100644 --- a/src/system/kernel/platform/u-boot/Jamfile +++ b/src/system/kernel/platform/u-boot/Jamfile @@ -5,7 +5,22 @@ SubDirC++Flags $(TARGET_KERNEL_PIC_CCFLAGS) ; UseLibraryHeaders [ FDirName libfdt ] ; +local libFDTSources = + fdt.c + fdt_ro.c + fdt_rw.c + fdt_strerror.c + fdt_sw.c + fdt_wip.c +; + KernelMergeObject kernel_platform_u-boot.o : platform.cpp + fdt_support.cpp openfirmware.cpp + $(libFDTSources) ; + +SEARCH on [ FGristFiles $(libFDTSources) ] + = [ FDirName $(HAIKU_TOP) src libs libfdt ] ; + diff --git a/src/system/boot/platform/u-boot/fdt_support.cpp b/src/system/kernel/platform/u-boot/fdt_support.cpp similarity index 96% rename from src/system/boot/platform/u-boot/fdt_support.cpp rename to src/system/kernel/platform/u-boot/fdt_support.cpp index d0ac350ae8..fe05f6f9ad 100644 --- a/src/system/boot/platform/u-boot/fdt_support.cpp +++ b/src/system/kernel/platform/u-boot/fdt_support.cpp @@ -15,6 +15,10 @@ extern "C" { #include }; +#ifndef _BOOT_MODE +/* the bootloader has it in asm code to avoid it ending up in .bss */ +void *gFDT; +#endif extern "C" void dump_fdt(const void *fdt); From 6ccf5f95c0432e9167235c458e9d2a493065611d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Wed, 19 Dec 2012 15:34:23 +0100 Subject: [PATCH 023/137] sam460ex: add port notes (org-mode format) --- docs/develop/ports/ppc/sam460ex/notes.txt | 64 +++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 docs/develop/ports/ppc/sam460ex/notes.txt diff --git a/docs/develop/ports/ppc/sam460ex/notes.txt b/docs/develop/ports/ppc/sam460ex/notes.txt new file mode 100644 index 0000000000..7ce424099e --- /dev/null +++ b/docs/develop/ports/ppc/sam460ex/notes.txt @@ -0,0 +1,64 @@ +Notes on Sam460ex Haiku port -*- org -*- + +* U-Boot commands +** no-fdt no-initrd +# (seems the U-Boot input buffer is quite limited, can't paste much more on single line in minicom) +setenv ipaddr 192.168.4.100; tftpboot 0x4000000 192.168.4.2:haiku_loader_linux.ub; bootm 0x4000000 +** with FDT and tgz as initrd +setenv ipaddr 192.168.4.100 +tftpboot 0x4000000 192.168.4.2:haiku_loader_linux.ub +tftpboot 0x8000000 192.168.4.2:haiku_initrd.ub +tftpboot 0xc000000 192.168.4.2:sam460ex.dtb +fdt addr 0xc000000 +fdt header +bootm 0x4000000 0x8000000 0xc000000 plop + +* TODO U-Boot API? +** TODO move Partenope hack to proper official U-Boot API? +** TODO reserved regs? +BoardSetup +=:? +TARGET_BOOT_CCFLAGS += -ffixed-r2 -ffixed-r14 -ffixed-r29 ; +TARGET_BOOT_C++FLAGS += -ffixed-r2 -ffixed-r14 -ffixed-r29 ; + +* Other ports +** AROS port +https://www.gitorious.org/aros/aros/commits/sam460 +** Linux port +http://kernel.org/doc/ols/2003/ols2003-pages-340-350.pdf +** NetBSD +https://wiki.netbsd.org/users/rkujawa/sam4x0/ + +* PPC +** Classic +http://class.ee.iastate.edu/cpre211/labs/quickrefPPC.html +http://www.ibm.com/developerworks/library/l-ppc/ +http://www.csd.uwo.ca/~mburrel/stuff/ppc-asm.html +** Book-E +http://www.linux-kvm.org/page/PowerPC_Book_E_MMU +http://wiki.freebsd.org/powerpc/BookE +http://en.wikipedia.org/wiki/Memory_management_unit#PowerPC +** 440 +*** amcc 4x0 +http://c0ff33.net/drop/PPC440_UM2013.pdf +http://www.embeddeddeveloper.com/assets/processors/amcc/datasheets/PP460EX_DS2063.pdf +*** Freescale 440 (different mmu!!) +http://www.freescale.com/files/32bit/doc/white_paper/POWRPCARCPRMRM.pdf + +* FDT +http://www.denx.de/wiki/U-Boot/UBootFdtInfo +http://wiki.freebsd.org/FlattenedDeviceTree#Supporting_library_.28libfdt.29 +(see also arm docs) +** Sam440 dts +http://lxr.linux.no/linux+v3.4/arch/powerpc/boot/dts/sam440ep.dts +** Sam460ex dts: identical to amcc,Canyonlands !? +http://www.denx.de/wiki/view/DULG/Appendix#Section_13.1. + +* OF framebuffer +(not really usable from U-Boot (yet?)) +http://www.feedface.com/howto/forth.html +http://mail-index.netbsd.org/port-macppc/2004/12/13/0046.html +http://lists.freebsd.org/pipermail/svn-src-user/2012-January/004806.html +http://www.openfirmware.info/Bindings + +* TODO kdebug/disasm/ppc +http://code.google.com/p/ppcd/ From 0e4a0c0e7fedbb6e853dd858d090ad507f3a85a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Wed, 19 Dec 2012 16:08:49 +0100 Subject: [PATCH 024/137] sam460ex: one more address in the notes --- docs/develop/ports/ppc/sam460ex/notes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/develop/ports/ppc/sam460ex/notes.txt b/docs/develop/ports/ppc/sam460ex/notes.txt index 7ce424099e..767fd5c8fb 100644 --- a/docs/develop/ports/ppc/sam460ex/notes.txt +++ b/docs/develop/ports/ppc/sam460ex/notes.txt @@ -38,6 +38,7 @@ http://www.linux-kvm.org/page/PowerPC_Book_E_MMU http://wiki.freebsd.org/powerpc/BookE http://en.wikipedia.org/wiki/Memory_management_unit#PowerPC ** 440 +http://elinux.org/Book_E_and_PPC_440 *** amcc 4x0 http://c0ff33.net/drop/PPC440_UM2013.pdf http://www.embeddeddeveloper.com/assets/processors/amcc/datasheets/PP460EX_DS2063.pdf From ef7bb168f77d9d3537cc0b08bedbe70d50c86924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Wed, 2 Jan 2013 02:07:06 +0100 Subject: [PATCH 025/137] U-Boot: fix warnings --- src/system/boot/platform/u-boot/console.cpp | 2 ++ src/system/boot/platform/u-boot/devices.cpp | 2 +- src/system/boot/platform/u-boot/serial.cpp | 4 ++++ src/system/boot/platform/u-boot/start.cpp | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/system/boot/platform/u-boot/console.cpp b/src/system/boot/platform/u-boot/console.cpp index 62293e464c..1ff4694278 100644 --- a/src/system/boot/platform/u-boot/console.cpp +++ b/src/system/boot/platform/u-boot/console.cpp @@ -45,10 +45,12 @@ static SerialConsole sSerial; FILE *stdin, *stdout, *stderr; +/* static void scroll_up() { } +*/ // #pragma mark - diff --git a/src/system/boot/platform/u-boot/devices.cpp b/src/system/boot/platform/u-boot/devices.cpp index 650211b6ee..8a77d92713 100644 --- a/src/system/boot/platform/u-boot/devices.cpp +++ b/src/system/boot/platform/u-boot/devices.cpp @@ -28,7 +28,7 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList) if (!args->platform.boot_tgz_data || !args->platform.boot_tgz_size) return B_DEVICE_NOT_FOUND; - TRACE("Memory Disk at: %lx size: %lx\n", args->platform.boot_tgz_data, + TRACE("Memory Disk at: %p size: %lx\n", args->platform.boot_tgz_data, args->platform.boot_tgz_size); MemoryDisk* disk = new(nothrow) MemoryDisk( diff --git a/src/system/boot/platform/u-boot/serial.cpp b/src/system/boot/platform/u-boot/serial.cpp index 27bbb812a1..61093ceb91 100644 --- a/src/system/boot/platform/u-boot/serial.cpp +++ b/src/system/boot/platform/u-boot/serial.cpp @@ -165,9 +165,13 @@ serial_init_fdt(const void *fdt) || fdt_node_check_compatible(fdt, node, "ns16550") == 1) { gUART = arch_get_uart_8250(regs, clock); //dprintf("serial: using 8250\n"); + // XXX:assume speed is already set + (void)speed; return; } + // for when we can use U-Boot's console + panic("Unknown UART type %s", type); } diff --git a/src/system/boot/platform/u-boot/start.cpp b/src/system/boot/platform/u-boot/start.cpp index 074e434f07..1bcc0d346f 100644 --- a/src/system/boot/platform/u-boot/start.cpp +++ b/src/system/boot/platform/u-boot/start.cpp @@ -115,7 +115,7 @@ platform_start_kernel(void) status_t error = arch_start_kernel(&gKernelArgs, kernelEntry, stackTop); - panic("kernel returned!\n"); + panic("kernel returned %lx!\n", error); } From f4b31e85b54a0665a5db0cffafb8a18a965fe38c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 18 Feb 2013 00:16:56 +0100 Subject: [PATCH 026/137] U-Boot: PPC: Spice up CPU detection, trying both PVR and FDT * Read the PVR register to determine the CPU type. * Also check the FDT /cpu/cpu@0 node for model string (we use the FDT calls directly since the OF wrapper isn't initialized yet). * Use this to enable the FPU APU hack for 440 (instead of #ifdef). --- .../boot/platform/u-boot/arch/ppc/Jamfile | 2 + .../platform/u-boot/arch/ppc/arch_cpu.cpp | 86 ++++++++++++++++--- 2 files changed, 77 insertions(+), 11 deletions(-) diff --git a/src/system/boot/platform/u-boot/arch/ppc/Jamfile b/src/system/boot/platform/u-boot/arch/ppc/Jamfile index 54f465975e..ba93a441a1 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/Jamfile +++ b/src/system/boot/platform/u-boot/arch/ppc/Jamfile @@ -6,6 +6,8 @@ UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] [ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ; UsePrivateHeaders [ FDirName kernel arch $(TARGET_KERNEL_ARCH) board $(TARGET_BOOT_BOARD) ] ; +UseLibraryHeaders [ FDirName libfdt ] ; + SubDirC++Flags -fno-rtti ; BootMergeObject boot_platform_u-boot_ppc.o : diff --git a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp index 5ea5245fb3..682ae82752 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp +++ b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp @@ -22,8 +22,16 @@ #include +extern "C" { +#include +#include +#include +}; -//#define TRACE_CPU + +extern void *gFDT; + +#define TRACE_CPU #ifdef TRACE_CPU # define TRACE(x) dprintf x #else @@ -44,17 +52,67 @@ static status_t check_cpu_features() { uint32 msr; + uint32 pvr; + bool is_440 = false; + bool is_460 = false; + bool pvr_unknown = false; + bool fdt_unknown = true; + const char *fdt_model = NULL; -#if BOARD_CPU_TYPE_PPC440 - // the FPU is implemented as an Auxiliary Processing Unit, - // so we must enable transfers by setting the DAPUIB bit to 0 - asm volatile( - "mfccr0 %%r3\n" - "\tlis %%r4,~(1<<(20-16))\n" - "\tand %%r3,%%r3,%%r4\n" - "\tmtccr0 %%r3" - : : : "r3", "r4"); -#endif + // attempt to detect processor version, either from PVR or FDT + // TODO:someday we'll support other things than 440/460... + + // read the Processor Version Register + pvr = get_pvr(); + uint16 version = (uint16)(pvr >> 16); + uint16 revision = (uint16)(pvr & 0xffff); + + switch (version) { + case AMCC440EP: + is_440 = true; + break; + case AMCC460EX: + is_460 = true; + break; + default: + pvr_unknown = true; + } + + // if we have an FDT... + // XXX: use it only as fallback? + if (gFDT != NULL/* && pvr_unknown*/) { + // TODO: for MP support we must checn /chosen/cpu first + int node = fdt_path_offset(gFDT, "/cpus/cpu@0"); + int len; + + fdt_model = (const char *)fdt_getprop(gFDT, node, "model", &len); + // TODO: partial match ? "PowerPC,440" && isalpha(next char) ? + if (fdt_model) { + if (!strcmp(fdt_model, "PowerPC,440EP")) { + is_440 = true; + fdt_unknown = false; + } else if (!strcmp(fdt_model, "PowerPC,460EX")) { + is_460 = true; + fdt_unknown = false; + } + } + } + + if (is_460) + is_440 = true; + + // some cpu-dependent tweaking + + if (is_440) { + // the FPU is implemented as an Auxiliary Processing Unit, + // so we must enable transfers by setting the DAPUIB bit to 0 + asm volatile( + "mfccr0 %%r3\n" + "\tlis %%r4,~(1<<(20-16))\n" + "\tand %%r3,%%r3,%%r4\n" + "\tmtccr0 %%r3" + : : : "r3", "r4"); + } // we do need an FPU for vsnprintf to work // on Sam460ex at least U-Boot doesn't enable the FPU for us @@ -68,6 +126,11 @@ check_cpu_features() return B_ERROR; } + TRACE(("CPU detection:\n")); + TRACE(("PVR revision %sknown: 0x%8lx\n", pvr_unknown ? "un" : "", pvr)); + TRACE(("FDT model %sknown: %s\n", fdt_unknown ? "un" : "", fdt_model)); + TRACE(("flags: %s440 %s460\n", is_440 ? "" : "!", is_460 ? "" : "!")); + return B_OK; } @@ -103,6 +166,7 @@ boot_arch_cpu_init(void) gKernelArgs.num_cpus = 1; // this will eventually be corrected later on + // TODO:iterate on /cpus/* return B_OK; } From 5bdc10121bb8eabc3921db5d950ff5c96eb81b3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 18 Feb 2013 00:42:10 +0100 Subject: [PATCH 027/137] U-Boot: use FDT call directly in of_init() in OF wrapper This avoids calling dprintf() and allows calling it earlier. --- src/system/kernel/platform/u-boot/openfirmware.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/platform/u-boot/openfirmware.cpp b/src/system/kernel/platform/u-boot/openfirmware.cpp index 557f4e5bc2..12115b12b6 100644 --- a/src/system/kernel/platform/u-boot/openfirmware.cpp +++ b/src/system/kernel/platform/u-boot/openfirmware.cpp @@ -49,7 +49,8 @@ static int fdt2of(int err) status_t of_init(int (*openFirmwareEntry)(void *)) { - gChosen = of_finddevice("/chosen"); + gChosen = fdt2of(fdt_path_offset(gFDT, "/chosen")); + if (gChosen == OF_FAILED) return B_ERROR; From 307c6177df9c9bce3d361bdb2dee278874adbf7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 18 Feb 2013 00:47:22 +0100 Subject: [PATCH 028/137] U-Boot: cleanup OpenFirmware wrapper tracing --- .../kernel/platform/u-boot/openfirmware.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/platform/u-boot/openfirmware.cpp b/src/system/kernel/platform/u-boot/openfirmware.cpp index 12115b12b6..9d2431551c 100644 --- a/src/system/kernel/platform/u-boot/openfirmware.cpp +++ b/src/system/kernel/platform/u-boot/openfirmware.cpp @@ -15,6 +15,13 @@ extern "C" { #include }; +#define TRACE_OF +#ifdef TRACE_OF +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + // FIXME: HACK: until we support multiple platforms at once in the kernel. @@ -92,7 +99,8 @@ of_finddevice(const char *device) name = fdt_get_alias(gFDT, device); node = fdt_path_offset(gFDT, name); -dprintf("of_finddevice('%s') name='%s' node=%d ret=%d\n", device, name, node, fdt2of(node)); + TRACE(("of_finddevice('%s') name='%s' node=%d ret=%d\n", device, name, node, + fdt2of(node))); return fdt2of(node); } @@ -152,11 +160,15 @@ of_instance_to_package(int instance) int of_getprop(int package, const char *property, void *buffer, int bufferSize) { -int oldSize = bufferSize; + int oldSize = bufferSize; const void *p = fdt_getprop(gFDT, package, property, &bufferSize); -dprintf("of_getprop(%d, '%s', , %d) =%p sz=%d ret=%d\n", package, property, oldSize, p, bufferSize, fdt2of(bufferSize)); + + TRACE(("of_getprop(%d, '%s', , %d) =%p sz=%d ret=%d\n", package, property, + oldSize, p, bufferSize, fdt2of(bufferSize))); + if (p == NULL) return fdt2of(bufferSize); + memcpy(buffer, p, bufferSize); return bufferSize; } From 219f59da1fa25ddd8596efe1c83f2fa45eb2c103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 18 Feb 2013 00:52:31 +0100 Subject: [PATCH 029/137] U-Boot: bail out in of_init() if no FDT passed --- src/system/kernel/platform/u-boot/openfirmware.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/system/kernel/platform/u-boot/openfirmware.cpp b/src/system/kernel/platform/u-boot/openfirmware.cpp index 9d2431551c..9a56ce93ce 100644 --- a/src/system/kernel/platform/u-boot/openfirmware.cpp +++ b/src/system/kernel/platform/u-boot/openfirmware.cpp @@ -56,6 +56,9 @@ static int fdt2of(int err) status_t of_init(int (*openFirmwareEntry)(void *)) { + if (gFDT == NULL) + return OF_FAILED; + gChosen = fdt2of(fdt_path_offset(gFDT, "/chosen")); if (gChosen == OF_FAILED) From acc4e245de592de1897b78b16f1f4dffbda07249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 18 Feb 2013 00:58:16 +0100 Subject: [PATCH 030/137] U-Boot: Typo --- src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp index 682ae82752..ac3a0a6b0b 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp +++ b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp @@ -81,7 +81,7 @@ check_cpu_features() // if we have an FDT... // XXX: use it only as fallback? if (gFDT != NULL/* && pvr_unknown*/) { - // TODO: for MP support we must checn /chosen/cpu first + // TODO: for MP support we must check /chosen/cpu first int node = fdt_path_offset(gFDT, "/cpus/cpu@0"); int len; From aa9d092029e1a8e2ee21f04cd321e8c3368f6deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 18 Feb 2013 02:40:16 +0100 Subject: [PATCH 031/137] U-Boot: implement of_get_next_device() in the OF wrapper --- .../kernel/platform/u-boot/openfirmware.cpp | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/platform/u-boot/openfirmware.cpp b/src/system/kernel/platform/u-boot/openfirmware.cpp index 9a56ce93ce..cdf2d27eb6 100644 --- a/src/system/kernel/platform/u-boot/openfirmware.cpp +++ b/src/system/kernel/platform/u-boot/openfirmware.cpp @@ -112,7 +112,38 @@ status_t of_get_next_device(int *_cookie, int root, const char *type, char *path, size_t pathSize) { - return B_ERROR; + int next; + int err; + + int startoffset = *_cookie ? *_cookie : -1; +// if (startoffset < 0 && root != 0) +// startoffset = root; + + // iterate by property value + next = fdt_node_offset_by_prop_value(gFDT, startoffset, "device_type", + type, strlen(type) + 1); + TRACE(("of_get_next_device(c:%d, %d, '%s', %p, %zd) soffset=%d next=%d\n", + *_cookie, root, type, path, pathSize, startoffset, fdt2of(next))); + if (next < 0) + return B_ENTRY_NOT_FOUND; + + // make sure root is the parent + int parent = next; + while (root && parent) { + parent = fdt_parent_offset(gFDT, parent); + if (parent == root) + break; + if (parent <= 0) + return B_ENTRY_NOT_FOUND; + } + + *_cookie = next; + + err = fdt_get_path(gFDT, next, path, pathSize); + if (err < 0) + return B_ERROR; + + return B_OK; } From 05e65058fed7b28b90560bf20fb4fe4ae149ed14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 18 Feb 2013 02:41:16 +0100 Subject: [PATCH 032/137] U-Boot: cleanup --- src/system/kernel/platform/u-boot/openfirmware.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/system/kernel/platform/u-boot/openfirmware.cpp b/src/system/kernel/platform/u-boot/openfirmware.cpp index cdf2d27eb6..5fb8f2c624 100644 --- a/src/system/kernel/platform/u-boot/openfirmware.cpp +++ b/src/system/kernel/platform/u-boot/openfirmware.cpp @@ -116,8 +116,6 @@ of_get_next_device(int *_cookie, int root, const char *type, char *path, int err; int startoffset = *_cookie ? *_cookie : -1; -// if (startoffset < 0 && root != 0) -// startoffset = root; // iterate by property value next = fdt_node_offset_by_prop_value(gFDT, startoffset, "device_type", From 4c50a9bcfd5f92310d3a3493381c9042f6ef5df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 18 Feb 2013 02:42:03 +0100 Subject: [PATCH 033/137] U-Boot: move of_init() call before cpu_init() So we can use the OF wrapper there as well and copy code verbatim from the OF platform. --- src/system/boot/platform/u-boot/start.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/system/boot/platform/u-boot/start.cpp b/src/system/boot/platform/u-boot/start.cpp index 1bcc0d346f..15838ebc83 100644 --- a/src/system/boot/platform/u-boot/start.cpp +++ b/src/system/boot/platform/u-boot/start.cpp @@ -191,6 +191,9 @@ start_raw(int argc, const char **argv) serial_init(gFDT); console_init(); + // initialize the OpenFirmware wrapper + of_init(NULL); + cpu_init(); if (args.platform.fdt_data) { @@ -223,9 +226,6 @@ start_raw(int argc, const char **argv) args.platform.boot_tgz_data, args.platform.boot_tgz_size); } } - - // also initialize the OpenFirmware wrapper - of_init(NULL); } // if we get passed a uimage, try to find the second blob From 0255210b042a1beeb3dbc72ae118c325031328b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 18 Feb 2013 02:47:34 +0100 Subject: [PATCH 034/137] U-Boot: PPC: properly enumerate CPUs * Code comes almost verbatim from OF platform. * Only bus frequency needs to be read from the /plb node instead. --- .../platform/u-boot/arch/ppc/arch_cpu.cpp | 121 ++++++++++++++++-- 1 file changed, 111 insertions(+), 10 deletions(-) diff --git a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp index ac3a0a6b0b..3bb9bfe392 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp +++ b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp @@ -19,9 +19,12 @@ #include #include #include +#include +#include #include +// TODO: try to move remaining FDT code to OF calls extern "C" { #include #include @@ -38,13 +41,112 @@ extern void *gFDT; # define TRACE(x) ; #endif -//uint32 gTimeConversionFactor; - -static void -calculate_cpu_conversion_factor() +static status_t +enumerate_cpus(void) { - #warning U-Boot:TODO! + // iterate through the "/cpus" node to find all CPUs + int cpus = of_finddevice("/cpus"); + if (cpus == OF_FAILED) { + printf("enumerate_cpus(): Failed to open \"/cpus\"!\n"); + return B_ERROR; + } + + char cpuPath[256]; + int cookie = 0; + int cpuCount = 0; + while (of_get_next_device(&cookie, cpus, "cpu", cpuPath, + sizeof(cpuPath)) == B_OK) { + TRACE(("found CPU: %s\n", cpuPath)); + + // For the first CPU get the frequencies of CPU, bus, and time base. + // We assume they are the same for all CPUs. + if (cpuCount == 0) { + int cpu = of_finddevice(cpuPath); + if (cpu == OF_FAILED) { + printf("enumerate_cpus: Failed get CPU device node!\n"); + return B_ERROR; + } + + // TODO: Does encode-int really encode quadlet (32 bit numbers) + // only? + int32 clockFrequency; + if (of_getprop(cpu, "clock-frequency", &clockFrequency, 4) + == OF_FAILED) { + printf("enumerate_cpus: Failed to get CPU clock " + "frequency!\n"); + return B_ERROR; + } + int32 busFrequency = 0; + if (of_getprop(cpu, "bus-frequency", &busFrequency, 4) + == OF_FAILED) { + //printf("enumerate_cpus: Failed to get bus clock " + // "frequency!\n"); + //return B_ERROR; + } + int32 timeBaseFrequency; + if (of_getprop(cpu, "timebase-frequency", &timeBaseFrequency, 4) + == OF_FAILED) { + printf("enumerate_cpus: Failed to get time base " + "frequency!\n"); + return B_ERROR; + } + + gKernelArgs.arch_args.cpu_frequency = clockFrequency; + gKernelArgs.arch_args.bus_frequency = busFrequency; + gKernelArgs.arch_args.time_base_frequency = timeBaseFrequency; + + TRACE((" CPU clock frequency: %ld\n", clockFrequency)); + //TRACE((" bus clock frequency: %ld\n", busFrequency)); + TRACE((" time base frequency: %ld\n", timeBaseFrequency)); + } + + cpuCount++; + } + + if (cpuCount == 0) { + printf("enumerate_cpus(): Found no CPUs!\n"); + return B_ERROR; + } + + gKernelArgs.num_cpus = cpuCount; + + // FDT doesn't list bus frequency on the cpu node but on the plb node + if (gKernelArgs.arch_args.bus_frequency == 0) { + int plb = of_finddevice("/plb"); + + int32 busFrequency = 0; + if (of_getprop(plb, "clock-frequency", &busFrequency, 4) + == OF_FAILED) { + printf("enumerate_cpus: Failed to get bus clock " + "frequency!\n"); + return B_ERROR; + } + gKernelArgs.arch_args.bus_frequency = busFrequency; + } + TRACE((" bus clock frequency: %ld\n", gKernelArgs.arch_args.bus_frequency)); + +#if 0 +//XXX:Classic + // allocate the kernel stacks (the memory stuff is already initialized + // at this point) + addr_t stack = (addr_t)arch_mmu_allocate((void*)0x80000000, + cpuCount * (KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE), + B_READ_AREA | B_WRITE_AREA, false); + if (!stack) { + printf("enumerate_cpus(): Failed to allocate kernel stack(s)!\n"); + return B_NO_MEMORY; + } + + for (int i = 0; i < cpuCount; i++) { + gKernelArgs.cpu_kstack[i].start = stack; + gKernelArgs.cpu_kstack[i].size = KERNEL_STACK_SIZE + + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE; + stack += KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE; + } +#endif + + return B_OK; } @@ -155,6 +257,8 @@ arch_spin(bigtime_t microseconds) extern "C" status_t boot_arch_cpu_init(void) { + // first check some features + // including some necessary for dprintf()... status_t err = check_cpu_features(); if (err != B_OK) { @@ -162,11 +266,8 @@ boot_arch_cpu_init(void) return err; } - calculate_cpu_conversion_factor(); - - gKernelArgs.num_cpus = 1; - // this will eventually be corrected later on - // TODO:iterate on /cpus/* + // now enumerate correctly all CPUs and get system frequencies + enumerate_cpus(); return B_OK; } From 85e1bac215444aa98118c71efa7ee953ece662fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 18 Feb 2013 03:39:09 +0100 Subject: [PATCH 035/137] U-Boot: Fix warning --- src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp index 3bb9bfe392..04ecebb603 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp +++ b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp @@ -124,7 +124,8 @@ enumerate_cpus(void) } gKernelArgs.arch_args.bus_frequency = busFrequency; } - TRACE((" bus clock frequency: %ld\n", gKernelArgs.arch_args.bus_frequency)); + TRACE((" bus clock frequency: %Ld\n", + gKernelArgs.arch_args.bus_frequency)); #if 0 //XXX:Classic From 00661368a2414389c5342b3ccb2940bd9c329d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 23 Feb 2013 04:01:19 +0100 Subject: [PATCH 036/137] PPC: Document how to automate TFTP-boot Haiku on Sam460ex * U-Boot seems to have a very small limit on serial or shell input buffer, so we split the commands into several variables that we run in sequence. --- docs/develop/ports/ppc/sam460ex/notes.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/develop/ports/ppc/sam460ex/notes.txt b/docs/develop/ports/ppc/sam460ex/notes.txt index 767fd5c8fb..0c9827f147 100644 --- a/docs/develop/ports/ppc/sam460ex/notes.txt +++ b/docs/develop/ports/ppc/sam460ex/notes.txt @@ -12,6 +12,15 @@ tftpboot 0xc000000 192.168.4.2:sam460ex.dtb fdt addr 0xc000000 fdt header bootm 0x4000000 0x8000000 0xc000000 plop +** for environment: +setenv booth1 'setenv ipaddr 192.168.4.100; tftpboot 0x4000000 192.168.4.2:haiku_loader_linux.ub' +setenv booth2 'tftpboot 0x8000000 192.168.4.2:haiku_initrd.ub' +setenv booth3 'tftpboot 0xc000000 192.168.4.2:sam460ex.dtb' +setenv booth4 'bootm 0x4000000 0x8000000 0xc000000 plop' +setenv booth 'run booth1; run booth2; run booth3; run booth4' +saveenv +run booth + * TODO U-Boot API? ** TODO move Partenope hack to proper official U-Boot API? From 2441f3ed909b7c670beb461f400235fef2b332af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 23 Feb 2013 18:25:36 +0100 Subject: [PATCH 037/137] PPC: add debug sections to the linked kernel Seems to be needed for gdb. --- src/system/ldscripts/ppc/kernel.ld | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/system/ldscripts/ppc/kernel.ld b/src/system/ldscripts/ppc/kernel.ld index 0814a0fb83..fbeb669074 100644 --- a/src/system/ldscripts/ppc/kernel.ld +++ b/src/system/ldscripts/ppc/kernel.ld @@ -91,6 +91,36 @@ SECTIONS _end = . ; + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* These must appear regardless of . */ + /* Strip unnecessary stuff */ /DISCARD/ : { *(.comment .note .eh_frame .dtors .debug_*) } From 80859e45b49c470b57723693ece6cc4a65cce901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 9 Mar 2013 03:20:12 +0100 Subject: [PATCH 038/137] PPC: Comment out cpu-specific compile flags for Sam460ex Userland and even kernel shouldn't require this anyway, cpu-specific code can still be compiled with those flags separately. --- build/jam/board/sam460ex/BoardSetup | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build/jam/board/sam460ex/BoardSetup b/build/jam/board/sam460ex/BoardSetup index 1f0b3369b0..1ab1d3e3d8 100644 --- a/build/jam/board/sam460ex/BoardSetup +++ b/build/jam/board/sam460ex/BoardSetup @@ -30,10 +30,10 @@ HAIKU_BOARD_LOADER_STACK_BASE = 0x02000000 ; # gcc flags for the specific cpu # -HAIKU_KERNEL_PIC_CCFLAGS += -mcpu=440fp -mtune=440fp ; -HAIKU_KERNEL_PIC_C++FLAGS += -mcpu=440fp -mtune=440fp ; -HAIKU_KERNEL_CCFLAGS += -mcpu=440fp -mtune=440fp ; -HAIKU_KERNEL_C++FLAGS += -mcpu=440fp -mtune=440fp ; -HAIKU_CCFLAGS += -mcpu=440fp -mtune=440fp ; -HAIKU_C++FLAGS += -mcpu=440fp -mtune=440fp ; +#HAIKU_KERNEL_PIC_CCFLAGS += -mcpu=440fp -mtune=440fp ; +#HAIKU_KERNEL_PIC_C++FLAGS += -mcpu=440fp -mtune=440fp ; +#HAIKU_KERNEL_CCFLAGS += -mcpu=440fp -mtune=440fp ; +#HAIKU_KERNEL_C++FLAGS += -mcpu=440fp -mtune=440fp ; +#HAIKU_CCFLAGS += -mcpu=440fp -mtune=440fp ; +#HAIKU_C++FLAGS += -mcpu=440fp -mtune=440fp ; From 6e809753b1678305bcdef617e820be6353791e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 9 Mar 2013 03:22:41 +0100 Subject: [PATCH 039/137] U-Boot: PPC: Include asm macros header Use the macros from the header instead of hardcoding. Add FUNCTION_END() call to help gdb. --- src/system/boot/platform/u-boot/arch/ppc/arch_start_kernel.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/system/boot/platform/u-boot/arch/ppc/arch_start_kernel.S b/src/system/boot/platform/u-boot/arch/ppc/arch_start_kernel.S index 2156e1d7a8..59d16fe9d0 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/arch_start_kernel.S +++ b/src/system/boot/platform/u-boot/arch/ppc/arch_start_kernel.S @@ -3,7 +3,8 @@ * All rights reserved. Distributed under the terms of the MIT License. */ -#define FUNCTION(x) .global x; .type x,@function; x +#include + /* status_t arch_start_kernel(struct kernel_args *kernelArgs, addr_t kernelEntry, addr_t kernelStackTop); @@ -46,4 +47,5 @@ FUNCTION(arch_start_kernel): mtlr %r0 addi %r1, %r1, 32 blr +FUNCTION_END(arch_start_kernel) From 0acc7a44b63a0a1351ac2ed837bfc14a98705422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 9 Mar 2013 03:26:53 +0100 Subject: [PATCH 040/137] PPC: Work-in-progress MMU definitions for AMCC440/460. Unfinished. the TLB entries require setting 3 registers plus another field for the PID. Didn't yet decide how to store this in the page tables. --- .../kernel/arch/ppc/arch_mmu_amcc440.h | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 headers/private/kernel/arch/ppc/arch_mmu_amcc440.h diff --git a/headers/private/kernel/arch/ppc/arch_mmu_amcc440.h b/headers/private/kernel/arch/ppc/arch_mmu_amcc440.h new file mode 100644 index 0000000000..5bc6f9d62a --- /dev/null +++ b/headers/private/kernel/arch/ppc/arch_mmu_amcc440.h @@ -0,0 +1,134 @@ +/* +** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ +#ifndef _KERNEL_ARCH_PPC_MMU_AMCC440_H +#define _KERNEL_ARCH_PPC_MMU_AMCC440_H + + +#include +#include + +#include + + +/*** TLB - translation lookaside buffer ***/ + +#define TLB_COUNT 64 + +/** valid tlb length values */ +enum tlb_length { + TLB_LENGTH_1kB = 0x0, + TLB_LENGTH_4kB = 0x1, + TLB_LENGTH_16kB = 0x2, + TLB_LENGTH_64kB = 0x3, + TLB_LENGTH_256kB = 0x4, + TLB_LENGTH_1MB = 0x5, + TLB_LENGTH_16MB = 0x7, + TLB_LENGTH_256MB = 0x9, +}; + +#define TLB_V 0x200 + +/** structure of a real TLB entry */ +//FIXME +struct tlb_entry { + // word 0 + uint32 effective_page_number : 22; + uint32 valid : 1; + uint32 translation_address_space : 1; + uint32 page_size : 4; + uint32 parity_1 : 4; + //uint32 translation_id : 8; +//FIXME:rest is Classic stuff + // word 0 + // upper 32 bit + uint32 page_index : 15; // BEPI, block effective page index + uint32 _reserved0 : 4; + uint32 length : 11; + uint32 kernel_valid : 1; // Vs, Supervisor-state valid + uint32 user_valid : 1; // Vp, User-state valid + // lower 32 bit + uint32 physical_block_number : 15; // BPRN + uint32 write_through : 1; // WIMG + uint32 caching_inhibited : 1; + uint32 memory_coherent : 1; + uint32 guarded : 1; + uint32 _reserved1 : 1; + uint32 protection : 2; + + tlb_entry() + { + Clear(); + } + + void SetVirtualAddress(void *address) + { + page_index = uint32(address) >> 17; + } + + void SetPhysicalAddress(void *address) + { + physical_block_number = uint32(address) >> 17; + } + + void Clear() + { + memset((void *)this, 0, sizeof(tlb_entry)); + } +}; + +#if 0 // XXX:Classic +/*** PTE - page table entry ***/ + +enum pte_protection { + PTE_READ_ONLY = 3, + PTE_READ_WRITE = 2, +}; + +struct page_table_entry { + // upper 32 bit + uint32 valid : 1; + uint32 virtual_segment_id : 24; + uint32 secondary_hash : 1; + uint32 abbr_page_index : 6; + // lower 32 bit + uint32 physical_page_number : 20; + uint32 _reserved0 : 3; + uint32 referenced : 1; + uint32 changed : 1; + uint32 write_through : 1; // WIMG + uint32 caching_inhibited : 1; + uint32 memory_coherent : 1; + uint32 guarded : 1; + uint32 _reserved1 : 1; + uint32 page_protection : 2; + + static uint32 PrimaryHash(uint32 virtualSegmentID, uint32 virtualAddress); + static uint32 SecondaryHash(uint32 virtualSegmentID, uint32 virtualAddress); + static uint32 SecondaryHash(uint32 primaryHash); +}; + +struct page_table_entry_group { + struct page_table_entry entry[8]; +}; + +extern void ppc_get_page_table(page_table_entry_group **_pageTable, size_t *_size); +extern void ppc_set_page_table(page_table_entry_group *pageTable, size_t size); + +static inline segment_descriptor +ppc_get_segment_register(void *virtualAddress) +{ + return (segment_descriptor)get_sr(virtualAddress); +} + + +static inline void +ppc_set_segment_register(void *virtualAddress, segment_descriptor segment) +{ + set_sr(virtualAddress, *(uint32 *)&segment); +} + +#endif + +#endif /* _KERNEL_ARCH_PPC_MMU_AMCC440_H */ From af63ede7a1fd24b4713800cdc7aabb7ae3e09a55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 9 Mar 2013 03:33:12 +0100 Subject: [PATCH 041/137] U-Boot: PPC: Implement Book-E MMU support in bootloader Unlike Classic PPC, Book-E CPUs do not have hardware page-table walk, rather only a limited set of software-managed TLBs. Also, translation is never disabled even when page-faulting. The Linux Book-E port pins part of the RAM in one or more TLBs, and allocates kernel memory from it for the kernel itself and exception vectors, as well as page tables. cf. http://kernel.org/doc/ols/2003/ols2003-pages-340-350.pdf We take a similar approach, but instead of using a tree-like page directory we reserve a large part of this mapped range for an hashed page table similar to the Classic one, to later allow factoring code out. The kernel and boot modules will also be allocated there, and the rest should be used as SLAB areas. Note doing so will not allow implementing proper permissions for the areas allocated there since they are all handled by a single TLB. Also note Book-E does not standardize the MMU implementation itself. For now only AMCC440 type MMU is supported. This will need to be cleaned up later on. --- .../boot/platform/u-boot/arch/ppc/Jamfile | 6 + .../platform/u-boot/arch/ppc/arch_cpu.cpp | 6 + .../platform/u-boot/arch/ppc/arch_mmu.cpp | 695 ++++-------------- .../u-boot/arch/ppc/arch_mmu_amcc440.cpp | 180 +++++ 4 files changed, 343 insertions(+), 544 deletions(-) create mode 100644 src/system/boot/platform/u-boot/arch/ppc/arch_mmu_amcc440.cpp diff --git a/src/system/boot/platform/u-boot/arch/ppc/Jamfile b/src/system/boot/platform/u-boot/arch/ppc/Jamfile index ba93a441a1..639e56fd35 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/Jamfile +++ b/src/system/boot/platform/u-boot/arch/ppc/Jamfile @@ -10,6 +10,11 @@ UseLibraryHeaders [ FDirName libfdt ] ; SubDirC++Flags -fno-rtti ; +BootMergeObject boot_platform_u-boot_ppc_amcc440.o : + arch_mmu_amcc440.cpp + : -fno-pic -mcpu=440 +; + BootMergeObject boot_platform_u-boot_ppc.o : # must come first to have _start_* at correct locations shell.S @@ -20,6 +25,7 @@ BootMergeObject boot_platform_u-boot_ppc.o : arch_cpu.cpp #mmu.cpp : -fno-pic + : boot_platform_u-boot_ppc_amcc440.o ; SEARCH on [ FGristFiles arch_cpu_asm.S ] diff --git a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp index 04ecebb603..b292d6b36d 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp +++ b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp @@ -42,6 +42,10 @@ extern void *gFDT; #endif +// FIXME: this is ugly; introduce a cpu type in kernel args +bool gIs440 = false; + + static status_t enumerate_cpus(void) { @@ -204,6 +208,8 @@ check_cpu_features() if (is_460) is_440 = true; + gIs440 = is_440; + // some cpu-dependent tweaking if (is_440) { diff --git a/src/system/boot/platform/u-boot/arch/ppc/arch_mmu.cpp b/src/system/boot/platform/u-boot/arch/ppc/arch_mmu.cpp index 640cf894b1..b58cb7fd7d 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/arch_mmu.cpp +++ b/src/system/boot/platform/u-boot/arch/ppc/arch_mmu.cpp @@ -26,527 +26,118 @@ #include +/*! This implements boot loader mmu support for Book-E PowerPC, + which only support a limited number of TLB and no hardware page table walk, + and does not standardize at how to use the mmu, requiring vendor-specific + code. + + Like Linux, we pin one of the TLB entries to a fixed translation, + however we use it differently. + cf. http://kernel.org/doc/ols/2003/ols2003-pages-340-350.pdf + + This translation uses a single large page (16 or 256MB are possible) which + directly maps the begining of the RAM. + We use it as a linear space to allocate from at boot time, + loading the kernel and modules into it, and other required data. + Near the end we reserve a page table (it doesn't need to be aligned), + but unlike Linux we use the same globally hashed page table that is + implemented by Classic PPC, to allow reusing code if possible, and also + to limit fragmentation which would occur by using a tree-based page table. + However this means we might actually run out of page table entries in case + of too many collisions. + + The kernel will then create areas to cover this already-mapped space. + This also means proper permission bits (RWX) will not be applicable to + separate areas which are enclosed by this mapping. + + We put the kernel stack at the end of the mapping so that the guard page is + outsite and thus unmapped. (we don't support SMP) +*/ + +/*! The (physical) memory layout of the boot loader is currently as follows: + 0x00000000 kernel + 0x00400000 ...modules + + (at least on the Sam460ex U-Boot; we'll need to accomodate other setups) + 0x01000000 boot loader + 0x01800000 Flattened Device Tree + 0x01900000 boot.tgz (= ramdisk) + 0x02000000 boot loader uimage + + + boot loader heap (should be discarded later on) + ... 256M-Kstack page hash table + ... 256M kernel stack + kernel stack guard page + + The kernel is mapped at KERNEL_BASE, all other stuff mapped by the + loader (kernel args, modules, driver settings, ...) comes after + 0x80040000 which means that there is currently only 4 MB reserved for + the kernel itself (see kMaxKernelSize). FIXME: downsize kernel_ppc +*/ + + int32 of_address_cells(int package); int32 of_size_cells(int package); -//#define TRACE_MMU +extern bool gIs440; +// XXX:use a base class for Book-E support? +extern status_t arch_mmu_setup_pinned_tlb_amcc440(phys_addr_t totalRam, + size_t &tableSize, size_t &tlbSize); + +#define TRACE_MMU #ifdef TRACE_MMU # define TRACE(x) dprintf x #else # define TRACE(x) ; #endif -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define TRACE_MEMORY_MAP - // Define this to print the memory map to serial debug, - // You also need to define ENABLE_SERIAL in serial.cpp - // for output to work. + // Define this to print the memory map to serial debug. -#ifdef __ARM__ +static const size_t kMaxKernelSize = 0x400000; // 4 MB for the kernel - -/* -TODO: - -recycle bit! -*/ - -/*! The (physical) memory layout of the boot loader is currently as follows: - 0x00000000 u-boot (run from NOR flash) - 0xa0000000 u-boot stuff like kernel arguments afaik - 0xa0100000 - 0xa0ffffff boot.tgz (up to 15MB probably never needed so big...) - 0xa1000000 - 0xa1ffffff pagetables - 0xa2000000 - ? code (up to 1MB) - 0xa2100000 boot loader heap / free physical memory - - The kernel is mapped at KERNEL_BASE, all other stuff mapped by the - loader (kernel args, modules, driver settings, ...) comes after - 0x80020000 which means that there is currently only 2 MB reserved for - the kernel itself (see kMaxKernelSize). -*/ - - -/* -*defines a block in memory -*/ -struct memblock { - const char name[16]; - // the name will be used for debugging etc later perhaps... - addr_t start; - // start of the block - addr_t end; - // end of the block - uint32 flags; - // which flags should be applied (device/normal etc..) -}; - - -static struct memblock LOADER_MEMORYMAP[] = { - { - "devices", - DEVICE_BASE, - DEVICE_BASE + DEVICE_SIZE - 1, - MMU_L2_FLAG_B, - }, - { - "RAM_loader", // 1MB loader - SDRAM_BASE + 0, - SDRAM_BASE + 0x0fffff, - MMU_L2_FLAG_C, - }, - { - "RAM_pt", // Page Table 1MB - SDRAM_BASE + 0x100000, - SDRAM_BASE + 0x1FFFFF, - MMU_L2_FLAG_C, - }, - { - "RAM_free", // 16MB free RAM (more but we don't map it automaticaly) - SDRAM_BASE + 0x0200000, - SDRAM_BASE + 0x11FFFFF, - MMU_L2_FLAG_C, - }, - { - "RAM_stack", // stack - SDRAM_BASE + 0x1200000, - SDRAM_BASE + 0x2000000, - MMU_L2_FLAG_C, - }, - { - "RAM_initrd", // stack - SDRAM_BASE + 0x2000000, - SDRAM_BASE + 0x2500000, - MMU_L2_FLAG_C, - }, - -#ifdef FB_BASE - { - "framebuffer", // 2MB framebuffer ram - FB_BASE, - FB_BASE + FB_SIZE - 1, - MMU_L2_FLAG_AP_RW|MMU_L2_FLAG_C, - }, -#endif -}; - - -//static const uint32 kDefaultPageTableFlags = MMU_FLAG_READWRITE; - // not cached not buffered, R/W -static const size_t kMaxKernelSize = 0x200000; // 2 MB for the kernel - -static addr_t sNextPhysicalAddress = 0; //will be set by mmu_init +static addr_t sNextPhysicalAddress = kMaxKernelSize; //will be set by mmu_init static addr_t sNextVirtualAddress = KERNEL_BASE + kMaxKernelSize; -static addr_t sMaxVirtualAddress = KERNEL_BASE + kMaxKernelSize; - -static addr_t sNextPageTableAddress = 0; -//the page directory is in front of the pagetable -static uint32 kPageTableRegionEnd = 0; +//static addr_t sMaxVirtualAddress = KERNEL_BASE + kMaxKernelSize; // working page directory and page table -static uint32 *sPageDirectory = 0 ; -//page directory has to be on a multiple of 16MB for -//some arm processors +static void *sPageTable = 0 ; static addr_t get_next_virtual_address(size_t size) { addr_t address = sNextVirtualAddress; + sNextPhysicalAddress += size; sNextVirtualAddress += size; return address; } -static addr_t -get_next_virtual_address_alligned (size_t size, uint32 mask) -{ - addr_t address = (sNextVirtualAddress) & mask; - sNextVirtualAddress = address + size; - - return address; -} - - static addr_t get_next_physical_address(size_t size) { addr_t address = sNextPhysicalAddress; sNextPhysicalAddress += size; + sNextVirtualAddress += size; return address; } -static addr_t -get_next_physical_address_alligned(size_t size, uint32 mask) -{ - addr_t address = sNextPhysicalAddress & mask; - sNextPhysicalAddress = address + size; - - return address; -} - - -static addr_t -get_next_virtual_page(size_t pagesize) -{ - return get_next_virtual_address_alligned(pagesize, 0xffffffc0); -} - - -static addr_t -get_next_physical_page(size_t pagesize) -{ - return get_next_physical_address_alligned(pagesize, 0xffffffc0); -} - - -/* - * Set translation table base - */ -void -mmu_set_TTBR(uint32 ttb) -{ - ttb &= 0xffffc000; - asm volatile("MCR p15, 0, %[adr], c2, c0, 0"::[adr] "r" (ttb)); -} - - -/* - * Flush the TLB - */ -void -mmu_flush_TLB() -{ - uint32 value = 0; - asm volatile("MCR p15, 0, %[c8format], c8, c7, 0"::[c8format] "r" (value)); -} - - -/* - * Read MMU Control Register - */ -uint32 -mmu_read_C1() -{ - uint32 controlReg = 0; - asm volatile("MRC p15, 0, %[c1out], c1, c0, 0":[c1out] "=r" (controlReg)); - return controlReg; -} - - -/* - * Write MMU Control Register - */ -void -mmu_write_C1(uint32 value) -{ - asm volatile("MCR p15, 0, %[c1in], c1, c0, 0"::[c1in] "r" (value)); -} - - -void -mmu_write_DACR(uint32 value) -{ - asm volatile("MCR p15, 0, %[c1in], c3, c0, 0"::[c1in] "r" (value)); -} - - -static uint32 * -get_next_page_table(uint32 type) -{ - TRACE(("get_next_page_table, sNextPageTableAddress %p, kPageTableRegionEnd " - "%p, type 0x" B_PRIX32 "\n", sNextPageTableAddress, - kPageTableRegionEnd, type)); - - size_t size = 0; - switch(type) { - case MMU_L1_TYPE_COARSE: - default: - size = 1024; - break; - case MMU_L1_TYPE_FINE: - size = 4096; - break; - case MMU_L1_TYPE_SECTION: - size = 16384; - break; - } - - addr_t address = sNextPageTableAddress; - if (address >= kPageTableRegionEnd) { - TRACE(("outside of pagetableregion!\n")); - return (uint32 *)get_next_physical_address_alligned(size, 0xffffffc0); - } - - sNextPageTableAddress += size; - return (uint32 *)address; -} - - -void -init_page_directory() -{ - TRACE(("init_page_directory\n")); - uint32 smalltype; - - // see if subpages disabled - if (mmu_read_C1() & (1<<23)) - smalltype = MMU_L2_TYPE_SMALLNEW; - else - smalltype = MMU_L2_TYPE_SMALLEXT; - - gKernelArgs.arch_args.phys_pgdir = (uint32)sPageDirectory; - - // clear out the pgdir - for (uint32 i = 0; i < 4096; i++) - sPageDirectory[i] = 0; - - uint32 *pageTable = NULL; - for (uint32 i = 0; i < ARRAY_SIZE(LOADER_MEMORYMAP);i++) { - - pageTable = get_next_page_table(MMU_L1_TYPE_COARSE); - TRACE(("BLOCK: %s START: %lx END %lx\n", LOADER_MEMORYMAP[i].name, - LOADER_MEMORYMAP[i].start, LOADER_MEMORYMAP[i].end)); - addr_t pos = LOADER_MEMORYMAP[i].start; - - int c = 0; - while (pos < LOADER_MEMORYMAP[i].end) { - pageTable[c] = pos | LOADER_MEMORYMAP[i].flags | smalltype; - - c++; - if (c > 255) { // we filled a pagetable => we need a new one - // there is 1MB per pagetable so: - sPageDirectory[VADDR_TO_PDENT(pos)] - = (uint32)pageTable | MMU_L1_TYPE_COARSE; - pageTable = get_next_page_table(MMU_L1_TYPE_COARSE); - c = 0; - } - - pos += B_PAGE_SIZE; - } - - if (c > 0) { - sPageDirectory[VADDR_TO_PDENT(pos)] - = (uint32)pageTable | MMU_L1_TYPE_COARSE; - } - } - - mmu_flush_TLB(); - - /* set up the translation table base */ - mmu_set_TTBR((uint32)sPageDirectory); - - mmu_flush_TLB(); - - /* set up the domain access register */ - mmu_write_DACR(0xFFFFFFFF); - - /* turn on the mmu */ - mmu_write_C1(mmu_read_C1() | 0x1); -} - - -/*! Adds a new page table for the specified base address */ -static void -add_page_table(addr_t base) -{ - TRACE(("add_page_table(base = %p)\n", (void *)base)); - - // Get new page table and clear it out - uint32 *pageTable = get_next_page_table(MMU_L1_TYPE_COARSE); -/* - if (pageTable > (uint32 *)(8 * 1024 * 1024)) { - panic("tried to add page table beyond the indentity mapped 8 MB " - "region\n"); - } -*/ - for (int32 i = 0; i < 256; i++) - pageTable[i] = 0; - - // put the new page table into the page directory - sPageDirectory[VADDR_TO_PDENT(base)] - = (uint32)pageTable | MMU_L1_TYPE_COARSE; -} - - -/*! Creates an entry to map the specified virtualAddress to the given - physicalAddress. - If the mapping goes beyond the current page table, it will allocate - a new one. If it cannot map the requested page, it panics. -*/ -static void -map_page(addr_t virtualAddress, addr_t physicalAddress, uint32 flags) -{ - TRACE(("map_page: vaddr 0x%lx, paddr 0x%lx\n", virtualAddress, - physicalAddress)); - - if (virtualAddress < KERNEL_BASE) { - panic("map_page: asked to map invalid page %p!\n", - (void *)virtualAddress); - } - - if (virtualAddress >= sMaxVirtualAddress) { - // we need to add a new page table - add_page_table(sMaxVirtualAddress); - sMaxVirtualAddress += B_PAGE_SIZE * 256; - - if (virtualAddress >= sMaxVirtualAddress) { - panic("map_page: asked to map a page to %p\n", - (void *)virtualAddress); - } - } - - physicalAddress &= ~(B_PAGE_SIZE - 1); - - // map the page to the correct page table - uint32 *pageTable - = (uint32 *)(sPageDirectory[VADDR_TO_PDENT(virtualAddress)] - & ARM_PDE_ADDRESS_MASK); - - TRACE(("map_page: pageTable 0x%lx\n", - sPageDirectory[VADDR_TO_PDENT(virtualAddress)] & ARM_PDE_ADDRESS_MASK)); - - if (pageTable == NULL) { - add_page_table(virtualAddress); - pageTable = (uint32 *)(sPageDirectory[VADDR_TO_PDENT(virtualAddress)] - & ARM_PDE_ADDRESS_MASK); - } - - uint32 tableEntry = VADDR_TO_PTENT(virtualAddress); - - TRACE(("map_page: inserting pageTable %p, tableEntry %ld, physicalAddress " - "%p\n", pageTable, tableEntry, physicalAddress)); - - pageTable[tableEntry] = physicalAddress | flags; - - mmu_flush_TLB(); - - TRACE(("map_page: done\n")); -} - - // #pragma mark - extern "C" addr_t mmu_map_physical_memory(addr_t physicalAddress, size_t size, uint32 flags) { - addr_t address = sNextVirtualAddress; - addr_t pageOffset = physicalAddress & (B_PAGE_SIZE - 1); - - physicalAddress -= pageOffset; - - for (addr_t offset = 0; offset < size; offset += B_PAGE_SIZE) { - map_page(get_next_virtual_page(B_PAGE_SIZE), physicalAddress + offset, - flags); - } - - return address + pageOffset; + panic("WRITEME"); + return 0; } -static void -unmap_page(addr_t virtualAddress) -{ - TRACE(("unmap_page(virtualAddress = %p)\n", (void *)virtualAddress)); - - if (virtualAddress < KERNEL_BASE) { - panic("unmap_page: asked to unmap invalid page %p!\n", - (void *)virtualAddress); - } - - // unmap the page from the correct page table - uint32 *pageTable - = (uint32 *)(sPageDirectory[VADDR_TO_PDENT(virtualAddress)] - & ARM_PDE_ADDRESS_MASK); - - pageTable[VADDR_TO_PTENT(virtualAddress)] = 0; - - mmu_flush_TLB(); -} - - -extern "C" void * -mmu_allocate(void *virtualAddress, size_t size) -{ - TRACE(("mmu_allocate: requested vaddr: %p, next free vaddr: 0x%lx, size: " - "%ld\n", virtualAddress, sNextVirtualAddress, size)); - - size = (size + B_PAGE_SIZE - 1) / B_PAGE_SIZE; - // get number of pages to map - - if (virtualAddress != NULL) { - // This special path is almost only useful for loading the - // kernel into memory; it will only allow you to map the - // 'kMaxKernelSize' bytes following the kernel base address. - // Also, it won't check for already mapped addresses, so - // you better know why you are here :) - addr_t address = (addr_t)virtualAddress; - - // is the address within the valid range? - if (address < KERNEL_BASE - || address + size >= KERNEL_BASE + kMaxKernelSize) { - TRACE(("mmu_allocate in illegal range\n address: %lx" - " KERNELBASE: %lx KERNEL_BASE + kMaxKernelSize: %lx" - " address + size : %lx \n", (uint32)address, KERNEL_BASE, - KERNEL_BASE + kMaxKernelSize, (uint32)(address + size))); - return NULL; - } - for (uint32 i = 0; i < size; i++) { - map_page(address, get_next_physical_page(B_PAGE_SIZE), - kDefaultPageFlags); - address += B_PAGE_SIZE; - } - - return virtualAddress; - } - - void *address = (void *)sNextVirtualAddress; - - for (uint32 i = 0; i < size; i++) { - map_page(get_next_virtual_page(B_PAGE_SIZE), - get_next_physical_page(B_PAGE_SIZE), kDefaultPageFlags); - } - - return address; -} - - -/*! This will unmap the allocated chunk of memory from the virtual - address space. It might not actually free memory (as its implementation - is very simple), but it might. -*/ -extern "C" void -mmu_free(void *virtualAddress, size_t size) -{ - TRACE(("mmu_free(virtualAddress = %p, size: %ld)\n", virtualAddress, size)); - - addr_t address = (addr_t)virtualAddress; - size = (size + B_PAGE_SIZE - 1) / B_PAGE_SIZE; - // get number of pages to map - - // is the address within the valid range? - if (address < KERNEL_BASE - || address + size >= KERNEL_BASE + kMaxKernelSize) { - panic("mmu_free: asked to unmap out of range region (%p, size %lx)\n", - (void *)address, size); - } - - // unmap all pages within the range - for (uint32 i = 0; i < size; i++) { - unmap_page(address); - address += B_PAGE_SIZE; - } - - if (address == sNextVirtualAddress) { - // we can actually reuse the virtual address space - sNextVirtualAddress -= size; - } -} -#endif - - /*! Sets up the final and kernel accessible GDT and IDT tables. BIOS calls won't work any longer after this function has been called. @@ -556,17 +147,7 @@ mmu_init_for_kernel(void) { TRACE(("mmu_init_for_kernel\n")); -#ifdef __ARM__ - // save the memory we've physically allocated - gKernelArgs.physical_allocated_range[0].size - = sNextPhysicalAddress - gKernelArgs.physical_allocated_range[0].start; - - // Save the memory we've virtually allocated (for the kernel and other - // stuff) - gKernelArgs.virtual_allocated_range[0].start = KERNEL_BASE; - gKernelArgs.virtual_allocated_range[0].size - = sNextVirtualAddress - KERNEL_BASE; - gKernelArgs.num_virtual_allocated_ranges = 1; + // TODO: remove all U-Boot TLB #ifdef TRACE_MEMORY_MAP { @@ -574,33 +155,35 @@ mmu_init_for_kernel(void) dprintf("phys memory ranges:\n"); for (i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) { - dprintf(" base 0x%08lx, length 0x%08lx\n", + dprintf(" base 0x%"B_PRIxPHYSADDR + ", length 0x%"B_PRIxPHYSADDR"\n", gKernelArgs.physical_memory_range[i].start, gKernelArgs.physical_memory_range[i].size); } dprintf("allocated phys memory ranges:\n"); for (i = 0; i < gKernelArgs.num_physical_allocated_ranges; i++) { - dprintf(" base 0x%08lx, length 0x%08lx\n", + dprintf(" base 0x%"B_PRIxPHYSADDR + ", length 0x%"B_PRIxPHYSADDR"\n", gKernelArgs.physical_allocated_range[i].start, gKernelArgs.physical_allocated_range[i].size); } dprintf("allocated virt memory ranges:\n"); for (i = 0; i < gKernelArgs.num_virtual_allocated_ranges; i++) { - dprintf(" base 0x%08lx, length 0x%08lx\n", + dprintf(" base 0x%"B_PRIxPHYSADDR + ", length 0x%"B_PRIxPHYSADDR"\n", gKernelArgs.virtual_allocated_range[i].start, gKernelArgs.virtual_allocated_range[i].size); } } #endif -#endif } -//XXX:move this +//TODO:move this to generic/ ? static status_t -find_physical_memory_ranges(size_t &total) +find_physical_memory_ranges(phys_addr_t &total) { int memory = -1; int package; @@ -700,64 +283,62 @@ find_physical_memory_ranges(size_t &total) extern "C" void mmu_init(void) { + size_t tableSize, tlbSize; + status_t err; TRACE(("mmu_init\n")); // get map of physical memory (fill in kernel_args structure) - size_t total; + phys_addr_t total; if (find_physical_memory_ranges(total) != B_OK) { dprintf("Error: could not find physical memory ranges!\n"); return /*B_ERROR*/; } - dprintf("total physical memory = %" B_PRId32 "MB\n", total / (1024 * 1024)); + dprintf("total physical memory = %" B_PRId64 "MB\n", total / (1024 * 1024)); -#ifdef __ARM__ - mmu_write_C1(mmu_read_C1() & ~((1<<29)|(1<<28)|(1<<0))); - // access flag disabled, TEX remap disabled, mmu disabled - - uint32 highestRAMAddress = SDRAM_BASE; - - // calculate lowest RAM adress from MEMORYMAP - for (uint32 i = 0; i < ARRAY_SIZE(LOADER_MEMORYMAP); i++) { - if (strcmp("RAM_free", LOADER_MEMORYMAP[i].name) == 0) - sNextPhysicalAddress = LOADER_MEMORYMAP[i].start; - - if (strcmp("RAM_pt", LOADER_MEMORYMAP[i].name) == 0) { - sNextPageTableAddress = LOADER_MEMORYMAP[i].start - + MMU_L1_TABLE_SIZE; - kPageTableRegionEnd = LOADER_MEMORYMAP[i].end; - sPageDirectory = (uint32 *) LOADER_MEMORYMAP[i].start; - } - - if (strncmp("RAM_", LOADER_MEMORYMAP[i].name, 4) == 0) { - if (LOADER_MEMORYMAP[i].end > highestRAMAddress) - highestRAMAddress = LOADER_MEMORYMAP[i].end; - } + // XXX: ugly, and wrong, there are several 440 mmu types... FIXME + if (gIs440) { + err = arch_mmu_setup_pinned_tlb_amcc440(total, tableSize, tlbSize); + dprintf("setup_pinned_tlb: 0x%08lx table %zdMB tlb %zdMB\n", + err, tableSize / (1024 * 1024), tlbSize / (1024 * 1024)); + } else { + panic("Unknown MMU type!"); + return; } - gKernelArgs.physical_memory_range[0].start = SDRAM_BASE; - gKernelArgs.physical_memory_range[0].size = highestRAMAddress - SDRAM_BASE; - gKernelArgs.num_physical_memory_ranges = 1; - - gKernelArgs.physical_allocated_range[0].start = SDRAM_BASE; - gKernelArgs.physical_allocated_range[0].size = 0; + // remember the start of the allocated physical pages + gKernelArgs.physical_allocated_range[0].start + = gKernelArgs.physical_memory_range[0].start; + gKernelArgs.physical_allocated_range[0].size = tlbSize; gKernelArgs.num_physical_allocated_ranges = 1; - // remember the start of the allocated physical pages + // Save the memory we've virtually allocated (for the kernel and other + // stuff) + gKernelArgs.virtual_allocated_range[0].start = KERNEL_BASE; + gKernelArgs.virtual_allocated_range[0].size + = tlbSize + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE; + gKernelArgs.num_virtual_allocated_ranges = 1; + + + sPageTable = (void *)(tlbSize - tableSize - KERNEL_STACK_SIZE); + // we put the page table near the end of the pinned TLB + TRACE(("page table at 0x%p to 0x%p\n", sPageTable, + (uint8 *)sPageTable + tableSize)); + + // map in a kernel stack + gKernelArgs.cpu_kstack[0].start = (addr_t)(tlbSize - KERNEL_STACK_SIZE); + gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE + + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE; + + TRACE(("kernel stack at 0x%Lx to 0x%Lx\n", gKernelArgs.cpu_kstack[0].start, + gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size)); + +#ifdef __ARM__ init_page_directory(); // map the page directory on the next vpage gKernelArgs.arch_args.vir_pgdir = mmu_map_physical_memory( (addr_t)sPageDirectory, MMU_L1_TABLE_SIZE, kDefaultPageFlags); - - // map in a kernel stack - gKernelArgs.cpu_kstack[0].start = (addr_t)mmu_allocate(NULL, - KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE); - gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE - + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE; - - TRACE(("kernel stack at 0x%lx to 0x%lx\n", gKernelArgs.cpu_kstack[0].start, - gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size)); #endif } @@ -769,22 +350,50 @@ extern "C" status_t platform_allocate_region(void **_address, size_t size, uint8 protection, bool /*exactAddress*/) { -#ifdef __ARM__ - void *address = mmu_allocate(*_address, size); + TRACE(("platform_allocate_region(&%p, %zd)\n", *_address, size)); + + //get_next_virtual_address + size = (size + B_PAGE_SIZE - 1) / B_PAGE_SIZE * B_PAGE_SIZE; + // roundup to page size for clarity + + if (*_address != NULL) { + // This special path is almost only useful for loading the + // kernel into memory; it will only allow you to map the + // 'kMaxKernelSize' bytes following the kernel base address. + // Also, it won't check for already mapped addresses, so + // you better know why you are here :) + addr_t address = (addr_t)*_address; + + // is the address within the valid range? + if (address < KERNEL_BASE + || address + size >= KERNEL_BASE + kMaxKernelSize) { + TRACE(("mmu_allocate in illegal range\n address: %lx" + " KERNELBASE: %lx KERNEL_BASE + kMaxKernelSize: %lx" + " address + size : %lx \n", (uint32)address, KERNEL_BASE, + KERNEL_BASE + kMaxKernelSize, (uint32)(address + size))); + return B_ERROR; + } + TRACE(("platform_allocate_region: allocated %zd bytes at %08lx\n", size, + address)); + + return B_OK; + } + + void *address = (void *)get_next_virtual_address(size); if (address == NULL) return B_NO_MEMORY; + TRACE(("platform_allocate_region: allocated %zd bytes at %p\n", size, + address)); *_address = address; return B_OK; -#else - return B_ERROR; -#endif } extern "C" status_t platform_free_region(void *address, size_t size) { + TRACE(("platform_free_region(%p, %zd)\n", address, size)); #ifdef __ARM__ mmu_free(address, size); #endif @@ -795,6 +404,7 @@ platform_free_region(void *address, size_t size) void platform_release_heap(struct stage2_args *args, void *base) { + //XXX // It will be freed automatically, since it is in the // identity mapped region, and not stored in the kernel's // page tables. @@ -804,15 +414,12 @@ platform_release_heap(struct stage2_args *args, void *base) status_t platform_init_heap(struct stage2_args *args, void **_base, void **_top) { -#ifdef __ARM__ - void *heap = (void *)get_next_physical_address(args->heap_size); - if (heap == NULL) - return B_NO_MEMORY; + // the heap is put right before the pagetable + void *heap = (uint8 *)sPageTable - args->heap_size; + //FIXME: use phys addresses to allow passing args to U-Boot? *_base = heap; *_top = (void *)((int8 *)heap + args->heap_size); + TRACE(("boot heap at 0x%p to 0x%p\n", *_base, *_top)); return B_OK; -#else - return B_ERROR; -#endif } diff --git a/src/system/boot/platform/u-boot/arch/ppc/arch_mmu_amcc440.cpp b/src/system/boot/platform/u-boot/arch/ppc/arch_mmu_amcc440.cpp new file mode 100644 index 0000000000..5077e63fba --- /dev/null +++ b/src/system/boot/platform/u-boot/arch/ppc/arch_mmu_amcc440.cpp @@ -0,0 +1,180 @@ +/* + * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. + * Based on code written by Travis Geiselbrecht for NewOS. + * + * Distributed under the terms of the MIT License. + */ + + +#include "mmu.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __ARM__ +#include +#endif +#include + +#include + +#include + +#include + +int32 of_address_cells(int package); +int32 of_size_cells(int package); + +#define TRACE_MMU +#ifdef TRACE_MMU +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + + +/*! Computes the recommended minimal page table size as + described in table 7-22 of the PowerPC "Programming + Environment for 32-Bit Microprocessors". + The page table size ranges from 64 kB (for 8 MB RAM) + to 32 MB (for 4 GB RAM). + FIXME: account for larger TLB descriptors for Book-E +*/ +static size_t +suggested_page_table_size(phys_addr_t total) +{ + uint32 max = 23; + // 2^23 == 8 MB + + while (max < 32) { + if (total <= (1UL << max)) + break; + + max++; + } + + return 1UL << (max - 7); + // 2^(23 - 7) == 64 kB +} + + +static void +read_TLB(int i, uint32 tlb[3], uint8 &pid) +{ + //FIXME:read pid too + asm volatile( + "tlbre %0,%3,0\n" + "\ttlbre %1,%3,1\n" + "\ttlbre %2,%3,2" + : "=r"(tlb[0]), + "=r"(tlb[1]), + "=r"(tlb[2]) + : "r"(i) + ); +} + + +static void +write_TLB(int i, uint32 tlb[3], uint8 pid) +{ + //FIXME:write pid too + asm volatile( + "tlbwe %0,%3,0\n" + "\ttlbwe %1,%3,1\n" + "\ttlbwe %2,%3,2" + : : "r"(tlb[0]), + "r"(tlb[1]), + "r"(tlb[2]), + "r"(i) + ); +} + + +static void +dump_TLBs(void) +{ + int i; + for (i = 0; i < TLB_COUNT; i++) { + uint32 tlb[3];// = { 0, 0, 0 }; + uint8 pid; + read_TLB(i, tlb, pid); + dprintf("TLB[%02d]: %08lx %08lx %08lx %02x\n", + i, tlb[0], tlb[1], tlb[2], pid); + } +} + + +status_t +arch_mmu_setup_pinned_tlb_amcc440(phys_addr_t totalRam, size_t &tableSize, + size_t &tlbSize) +{ + dump_TLBs(); + tlb_length tlbLength = TLB_LENGTH_16MB; +//XXX:totalRam = 4LL*1024*1024*1024; + + size_t suggestedTableSize = suggested_page_table_size(totalRam); + dprintf("suggested page table size = %" B_PRIuSIZE "\n", + suggestedTableSize); + + tableSize = suggestedTableSize; + + // add 4MB for kernel and some more for modules... + tlbSize = tableSize + 8 * 1024 * 1024; + + // round up to realistic TLB lengths, either 16MB or 256MB + // the unused space will be filled with SLAB areas + if (tlbSize < 16 * 1024 * 1024) + tlbSize = 16 * 1024 * 1024; + else { + tlbSize = 256 * 1024 * 1024; + tlbLength = TLB_LENGTH_256MB; + } + + uint32 tlb[3]; + uint8 pid; + int i; + + // Make sure the last TLB is free, else we are in trouble + // XXX: allow using a different TLB entry? + read_TLB(TLB_COUNT - 1, tlb, pid); + if ((tlb[0] & TLB_V) != 0) { + panic("Last TLB already in use. FIXME."); + return B_ERROR; + } + + // TODO: remove existing mapping from U-Boot at KERNEL_BASE !!! + // (on Sam460ex it's pci mem) + // for now we just move it to AS1 which we don't use, until calling + // the kernel. + // we could probably swap it with our own KERNEL_BASE TLB to call U-Boot + // if required, but it'd be quite ugly. + for (i = 0; i < TLB_COUNT; i++) { + read_TLB(i, tlb, pid); + //dprintf("tlb[%d][0] = %08lx\n", i, tlb[0]); + // TODO: make the test more complete and correct + if ((tlb[0] & 0xfffffc00) == KERNEL_BASE) { + tlb[0] |= 0x100; // AS1 + write_TLB(i, tlb, pid); + dprintf("Moved existing translation in TLB[%d] to AS1\n", i); + } + } + + // pin the last TLB + //XXX:also maybe skip the FDT + initrd + loader ? + phys_addr_t physBase = gKernelArgs.physical_memory_range[0].start; + //TODO:make sure 1st range is large enough? + i = TLB_COUNT - 1; // last one + pid = 0; // the kernel's PID + tlb[0] = (KERNEL_BASE | tlbLength << 4 | TLB_V); + tlb[1] = ((physBase & 0xfffffc00) | (physBase >> 32)); + tlb[2] = (0x0000003f); // user:RWX kernel:RWX + write_TLB(i, tlb, pid); + + return B_OK; +} + From 247db0d169987a50b75a5ad581cf33fd1e13202b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 21 Apr 2013 01:15:43 +0200 Subject: [PATCH 042/137] U-Boot: pass a copy of the FDT to the kernel --- .../kernel/boot/platform/u-boot/platform_kernel_args.h | 4 ++-- src/system/boot/platform/u-boot/start.cpp | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/headers/private/kernel/boot/platform/u-boot/platform_kernel_args.h b/headers/private/kernel/boot/platform/u-boot/platform_kernel_args.h index ae65dbc361..8a78bc69c4 100644 --- a/headers/private/kernel/boot/platform/u-boot/platform_kernel_args.h +++ b/headers/private/kernel/boot/platform/u-boot/platform_kernel_args.h @@ -22,8 +22,8 @@ typedef struct { void *openfirmware_entry; char rtc_path[128]; - // TODO: add FDT - char dummy; + // Flattened Device Tree blob + void *fdt; } platform_kernel_args; #endif /* KERNEL_BOOT_PLATFORM_UBOOT_KERNEL_ARGS_H */ diff --git a/src/system/boot/platform/u-boot/start.cpp b/src/system/boot/platform/u-boot/start.cpp index 15838ebc83..e1dbee62aa 100644 --- a/src/system/boot/platform/u-boot/start.cpp +++ b/src/system/boot/platform/u-boot/start.cpp @@ -105,6 +105,12 @@ platform_start_kernel(void) addr_t stackTop = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; + if (gFDT) { + // clone the Flattened Device Tree blob + gKernelArgs.platform_args.fdt = kernel_args_malloc(fdt_totalsize(gFDT)); + memcpy(gKernelArgs.platform_args.fdt, gFDT, fdt_totalsize(gFDT)); + } + // smp_init_other_cpus(); serial_cleanup(); mmu_init_for_kernel(); From 18ea985addc099a6feb5ba3ea86d55c999ef93be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 21 Apr 2013 02:08:24 +0200 Subject: [PATCH 043/137] U-Boot: PPC: set gFDT when passed to the kernel. --- src/system/kernel/arch/ppc/arch_platform.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/arch/ppc/arch_platform.cpp b/src/system/kernel/arch/ppc/arch_platform.cpp index 35e92adb0f..f83be42d20 100644 --- a/src/system/kernel/arch/ppc/arch_platform.cpp +++ b/src/system/kernel/arch/ppc/arch_platform.cpp @@ -15,6 +15,9 @@ #include +// TODO: declare this in some header +extern void *gFDT; + static PPCPlatform *sPPCPlatform; @@ -278,7 +281,9 @@ PPCUBoot::~PPCUBoot() status_t PPCUBoot::Init(struct kernel_args *kernelArgs) { - return B_ERROR; + gFDT = kernelArgs->platform_args.fdt; + // XXX: do we error out if no FDT? + return B_OK; } // InitSerialDebug From 0f8e6ba440c3bd10d40b793845ff38d446a6f24c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 21 Apr 2013 02:12:12 +0200 Subject: [PATCH 044/137] Typo --- src/system/boot/platform/u-boot/serial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/boot/platform/u-boot/serial.cpp b/src/system/boot/platform/u-boot/serial.cpp index 61093ceb91..ef94710504 100644 --- a/src/system/boot/platform/u-boot/serial.cpp +++ b/src/system/boot/platform/u-boot/serial.cpp @@ -131,7 +131,7 @@ serial_init_fdt(const void *fdt) return; // determine the MMIO address - // TODO: ppc640 use 64bit addressing, but U-Boot seems to map it below 4G, + // TODO: ppc460 use 64bit addressing, but U-Boot seems to map it below 4G, // and the FDT is not very clear. libfdt is also getting 64bit addr support. // so FIXME someday. prop = fdt_getprop(fdt, node, "virtual-reg", &len); From 94b802f5880405d4b08c44220ab45efcb6bf6721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 21 Apr 2013 03:16:46 +0200 Subject: [PATCH 045/137] U-Boot: PPC: Tell the kernel we come in peace from U-Boot --- src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp index b292d6b36d..83e887509d 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp +++ b/src/system/boot/platform/u-boot/arch/ppc/arch_cpu.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -264,6 +265,9 @@ arch_spin(bigtime_t microseconds) extern "C" status_t boot_arch_cpu_init(void) { + // This is U-Boot + gKernelArgs.arch_args.platform = PPC_PLATFORM_U_BOOT; + // first check some features // including some necessary for dprintf()... status_t err = check_cpu_features(); From 2e27c020cb5b3064b5d13fe044caa58cf94f0e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 21 Apr 2013 03:28:01 +0200 Subject: [PATCH 046/137] U-Boot: Factor-out debug UART setup from FDT for kernel use --- src/system/boot/platform/u-boot/serial.cpp | 83 +----------------- src/system/kernel/arch/ppc/Jamfile | 2 + .../kernel/platform/u-boot/fdt_support.cpp | 85 +++++++++++++++++++ 3 files changed, 90 insertions(+), 80 deletions(-) diff --git a/src/system/boot/platform/u-boot/serial.cpp b/src/system/boot/platform/u-boot/serial.cpp index ef94710504..4bf1a548e5 100644 --- a/src/system/boot/platform/u-boot/serial.cpp +++ b/src/system/boot/platform/u-boot/serial.cpp @@ -24,6 +24,8 @@ extern "C" { }; +extern "C" DebugUART *debug_uart_from_fdt(const void *fdt); + DebugUART* gUART; static int32 sSerialEnabled = 0; @@ -96,90 +98,11 @@ serial_cleanup(void) } -static void -serial_init_fdt(const void *fdt) -{ - const char *name; - const char *type; - int node; - int len; - phys_addr_t regs; - int32 clock = 0; - int32 speed = 0; - const void *prop; - - if (fdt == NULL) - return; - - name = fdt_get_alias(fdt, "serial"); - if (name == NULL) - name = fdt_get_alias(fdt, "serial0"); - if (name == NULL) - name = fdt_get_alias(fdt, "serial1"); - // TODO: else use /chosen linux,stdout-path - if (name == NULL) - return; - - node = fdt_path_offset(fdt, name); - //dprintf("serial: using '%s', node %d\n", name, node); - if (node < 0) - return; - - type = (const char *)fdt_getprop(fdt, node, "device_type", &len); - //dprintf("serial: type: '%s'\n", type); - if (type == NULL || strcmp(type, "serial")) - return; - - // determine the MMIO address - // TODO: ppc460 use 64bit addressing, but U-Boot seems to map it below 4G, - // and the FDT is not very clear. libfdt is also getting 64bit addr support. - // so FIXME someday. - prop = fdt_getprop(fdt, node, "virtual-reg", &len); - if (prop && len == 4) { - regs = fdt32_to_cpu(*(uint32_t *)prop); - //dprintf("serial: virtual-reg 0x%08llx\n", (int64)regs); - } else { - prop = fdt_getprop(fdt, node, "reg", &len); - if (prop && len >= 4) { - regs = fdt32_to_cpu(*(uint32_t *)prop); - //dprintf("serial: reg 0x%08llx\n", (int64)regs); - } else - return; - } - - // get the UART clock rate - prop = fdt_getprop(fdt, node, "clock-frequency", &len); - if (prop && len == 4) { - clock = fdt32_to_cpu(*(uint32_t *)prop); - //dprintf("serial: clock %ld\n", clock); - } - - // get current speed (XXX: not yet passed over) - prop = fdt_getprop(fdt, node, "current-speed", &len); - if (prop && len == 4) { - speed = fdt32_to_cpu(*(uint32_t *)prop); - //dprintf("serial: speed %ld\n", speed); - } - - if (fdt_node_check_compatible(fdt, node, "ns16550a") == 1 - || fdt_node_check_compatible(fdt, node, "ns16550") == 1) { - gUART = arch_get_uart_8250(regs, clock); - //dprintf("serial: using 8250\n"); - // XXX:assume speed is already set - (void)speed; - return; - } - - // for when we can use U-Boot's console - panic("Unknown UART type %s", type); -} - - extern "C" void serial_init(const void *fdt) { // first try with hints from the FDT - serial_init_fdt(fdt); + gUART = debug_uart_from_fdt(fdt); #ifdef BOARD_UART_DEBUG // fallback to hardcoded board UART diff --git a/src/system/kernel/arch/ppc/Jamfile b/src/system/kernel/arch/ppc/Jamfile index 493d20caa0..075c70ee73 100644 --- a/src/system/kernel/arch/ppc/Jamfile +++ b/src/system/kernel/arch/ppc/Jamfile @@ -26,6 +26,8 @@ KernelMergeObject kernel_arch_ppc.o : arch_vm.cpp arch_vm_translation_map.cpp arch_asm.S + debug_uart_8250.cpp + arch_uart_8250.cpp generic_vm_physical_page_mapper.cpp generic_vm_physical_page_ops.cpp diff --git a/src/system/kernel/platform/u-boot/fdt_support.cpp b/src/system/kernel/platform/u-boot/fdt_support.cpp index fe05f6f9ad..df4c79bde9 100644 --- a/src/system/kernel/platform/u-boot/fdt_support.cpp +++ b/src/system/kernel/platform/u-boot/fdt_support.cpp @@ -9,6 +9,9 @@ #include #include +#include +#include + extern "C" { #include #include @@ -21,6 +24,7 @@ void *gFDT; #endif extern "C" void dump_fdt(const void *fdt); +extern "C" DebugUART *debug_uart_from_fdt(const void *fdt); //#define FDT_DUMP_NODES //#define FDT_DUMP_PROPS @@ -117,3 +121,84 @@ void dump_fdt(const void *fdt) } +DebugUART * +debug_uart_from_fdt(const void *fdt) +{ + const char *name; + const char *type; + int node; + int len; + phys_addr_t regs; + int32 clock = 0; + int32 speed = 0; + const void *prop; + DebugUART *uart = NULL; + + if (fdt == NULL) + return NULL; + + name = fdt_get_alias(fdt, "serial"); + if (name == NULL) + name = fdt_get_alias(fdt, "serial0"); + if (name == NULL) + name = fdt_get_alias(fdt, "serial1"); + // TODO: else use /chosen linux,stdout-path + if (name == NULL) + return NULL; + + node = fdt_path_offset(fdt, name); + //dprintf("serial: using '%s', node %d\n", name, node); + if (node < 0) + return NULL; + + type = (const char *)fdt_getprop(fdt, node, "device_type", &len); + //dprintf("serial: type: '%s'\n", type); + if (type == NULL || strcmp(type, "serial")) + return NULL; + + // determine the MMIO address + // TODO: ppc460 use 64bit addressing, but U-Boot seems to map it below 4G, + // and the FDT is not very clear. libfdt is also getting 64bit addr support. + // so FIXME someday. + prop = fdt_getprop(fdt, node, "virtual-reg", &len); + if (prop && len == 4) { + regs = fdt32_to_cpu(*(uint32_t *)prop); + //dprintf("serial: virtual-reg 0x%08llx\n", (int64)regs); + } else { + prop = fdt_getprop(fdt, node, "reg", &len); + if (prop && len >= 4) { + regs = fdt32_to_cpu(*(uint32_t *)prop); + //dprintf("serial: reg 0x%08llx\n", (int64)regs); + } else + return NULL; + } + + // get the UART clock rate + prop = fdt_getprop(fdt, node, "clock-frequency", &len); + if (prop && len == 4) { + clock = fdt32_to_cpu(*(uint32_t *)prop); + //dprintf("serial: clock %ld\n", clock); + } + + // get current speed (XXX: not yet passed over) + prop = fdt_getprop(fdt, node, "current-speed", &len); + if (prop && len == 4) { + speed = fdt32_to_cpu(*(uint32_t *)prop); + //dprintf("serial: speed %ld\n", speed); + } + + if (fdt_node_check_compatible(fdt, node, "ns16550a") == 1 + || fdt_node_check_compatible(fdt, node, "ns16550") == 1) { + uart = arch_get_uart_8250(regs, clock); + //dprintf("serial: using 8250\n"); + // XXX:assume speed is already set + (void)speed; + } else { + // TODO: handle more UART types + // for when we can use U-Boot's console + panic("Unknown UART type %s", type); + } + + return uart; +} + From 3060b78cfcec4ca051a9ff234bf2f1451612dc53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 21 Apr 2013 03:29:48 +0200 Subject: [PATCH 047/137] PPC: Setup debug UART for kernel when booted from U-Boot Welcome to kernel debugger output! \o/ --- src/system/kernel/arch/ppc/arch_platform.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/system/kernel/arch/ppc/arch_platform.cpp b/src/system/kernel/arch/ppc/arch_platform.cpp index f83be42d20..5ed32287c1 100644 --- a/src/system/kernel/arch/ppc/arch_platform.cpp +++ b/src/system/kernel/arch/ppc/arch_platform.cpp @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -17,6 +18,7 @@ // TODO: declare this in some header extern void *gFDT; +extern "C" DebugUART *debug_uart_from_fdt(const void *fdt); static PPCPlatform *sPPCPlatform; @@ -256,6 +258,7 @@ private: int fInput; int fOutput; int fRTC; + DebugUART *fDebugUART; }; } // namespace BPrivate @@ -268,7 +271,8 @@ PPCUBoot::PPCUBoot() : PPCPlatform(PPC_PLATFORM_U_BOOT), fInput(-1), fOutput(-1), - fRTC(-1) + fRTC(-1), + fDebugUART(NULL) { } @@ -290,7 +294,10 @@ PPCUBoot::Init(struct kernel_args *kernelArgs) status_t PPCUBoot::InitSerialDebug(struct kernel_args *kernelArgs) { - return B_ERROR; + fDebugUART = debug_uart_from_fdt(gFDT); + if (fDebugUART == NULL) + return B_ERROR; + return B_OK; } // InitPostVM @@ -312,6 +319,8 @@ PPCUBoot::InitRTC(struct kernel_args *kernelArgs, char PPCUBoot::SerialDebugGetChar() { + if (fDebugUART) + return fDebugUART->GetChar(false); return 0; } @@ -319,6 +328,8 @@ PPCUBoot::SerialDebugGetChar() void PPCUBoot::SerialDebugPutChar(char c) { + if (fDebugUART) + fDebugUART->PutChar(c); } // SetHardwareRTC From d4659184b852a7aaa4d68ab0baa1369dfd542739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 1 Jun 2013 19:18:12 +0200 Subject: [PATCH 048/137] PPC: Add a 44x version of arch_exceptions.S For now just a copy of the classic code. --- src/system/kernel/arch/ppc/Jamfile | 1 + .../kernel/arch/ppc/arch_exceptions_44x.S | 441 ++++++++++++++++++ 2 files changed, 442 insertions(+) create mode 100644 src/system/kernel/arch/ppc/arch_exceptions_44x.S diff --git a/src/system/kernel/arch/ppc/Jamfile b/src/system/kernel/arch/ppc/Jamfile index 075c70ee73..7cc64b8060 100644 --- a/src/system/kernel/arch/ppc/Jamfile +++ b/src/system/kernel/arch/ppc/Jamfile @@ -14,6 +14,7 @@ KernelMergeObject kernel_arch_ppc.o : arch_debug.cpp arch_elf.cpp arch_exceptions.S + arch_exceptions_44x.S arch_int.cpp arch_mmu.cpp arch_platform.cpp diff --git a/src/system/kernel/arch/ppc/arch_exceptions_44x.S b/src/system/kernel/arch/ppc/arch_exceptions_44x.S new file mode 100644 index 0000000000..c4a1a60afa --- /dev/null +++ b/src/system/kernel/arch/ppc/arch_exceptions_44x.S @@ -0,0 +1,441 @@ +/* + * Copyright 2013, François Revol . + * All rights reserved. Distributed under the terms of the MIT License. + * + * Copyright 2006, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + * + * Copyright 2003, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ +#include + +/* General exception handling concept: + + The PPC architecture specifies entry point offsets for the various + exceptions in the first two physical pages. We put a short piece of code + (VEC_ENTRY()) into each exception vector. It calls exception_vector_common, + which is defined in the unused space at the beginning of the first physical + page. It re-enables address translation and calls ppc_exception_tail which + lies in the kernel. It dumps an iframe and invokes ppc_exception_entry() + (arch_int.cpp), which handles the exception and returns eventually. + The registers are restored from the iframe and we return from the + interrupt. + + algorithm overview: + + * VEC_ENTRY + * ppc_44x_exception_vector_common + * ppc_44x_exception_tail + - dump iframe + - ppc_exception_entry() + - restore registers and return from interrupt + + Here we use the following SPRG registers, which are at the disposal of the + operating system: + * SPRG0: Physical address pointer to a struct cpu_exception_context + for the current CPU. The structure contains helpful pointers + as well as some scratch memory for temporarily saving registers. + * SPRG1: Scratch. + + struct cpu_exception_context (defined in arch_int.h): + offset 0: virtual address of the exception handler routine in the kernel + offset 4: virtual address of the exception context + offset 8: kernel stack for the current thread + offset 12: start of scratch memory for saving registers etc. + + algorithm in detail: + + * VEC_ENTRY + - save r1 in SPRG1 and load cpu_exception_context into r1 + - save r0, save LR in r0 + * ppc_44x_exception_vector_common + - params: + . r0: old LR + . r1: exception context (physical address) + . SPRG1: original r1 + - save r0-3 + - load virtual exception context address to r1 + - turn on BAT for exception vector code + - turn on address translation + - get exception vector offset from LR + * ppc_44x_exception_tail + - params: + . r1: exception context (virtual address) + . r3: exception vector offset + . SPRG1: original r1 + - turn off BAT + - get kernel stack pointer + - dump iframe + - ppc_exception_entry() + - restore registers and return from interrupt + */ + + +/* exception vector definitions */ + +/* code in each exception vector */ +#define VEC_ENTRY() \ + mtsprg1 %r1 ; /* temporarily save r1 in SPRG1 */ \ + mfsprg0 %r1 ; /* ppc_cpu_exception_context* -> r1 */ \ + stw %r0, 16(%r1) ; /* save r0 */ \ + mflr %r0 ; /* save LR in r0 */ \ + bl ppc_44x_exception_vector_common ; /* continue with the common part */ + +/* defines an exception vector */ +#define DEFINE_VECTOR(offset, name) \ +.skip offset - (. - __44x_irqvec_start); \ +FUNCTION(ppc_44x_##name): \ + VEC_ENTRY() + + +.global __44x_irqvec_start +__44x_irqvec_start: + .long 0 + +/* Called by the exception vector code. + * LR: Points to the end of the exception vector code we're coming from. + * r0: original LR + * r1: ppc_cpu_exception_context* (physical address) + * SPRG1: original r1 + */ +ppc_44x_exception_vector_common: + stw %r0, 20(%r1) /* save original LR */ + stw %r2, 24(%r1) /* save r2 */ + stw %r3, 28(%r1) /* save r3 */ + + /* load the virtual address of the ppc_cpu_exception_context for this CPU */ + lwz %r1, 4(%r1) + + /* Address translation is turned off. We map this code via BAT, turn on + address translation, and continue in the kernel proper. */ + li %r0, 0x10|0x2 /* BATL_MC | BATL_PP_RW */ + mtibatl 0, %r0 /* load lower word of the instruction BAT */ + li %r0, 0x2 /* BEPI = 0, BL = 0 (128 KB), BATU_VS */ + mtibatu 0, %r0 /* load upper word of the instruction BAT */ + isync + sync + + /* turn on address translation */ + mfsrr1 %r0 /* load saved msr */ + rlwinm %r0, %r0, 28, 30, 31 /* extract mmu bits */ + mfmsr %r3 /* load the current msr */ + rlwimi %r3, %r0, 4, 26, 27 /* merge the mmu bits with the current msr */ + li %r0, 1 + rlwimi %r3, %r0, 13, 18, 18 /* turn on FPU, too */ + mtmsr %r3 /* load new msr (turning the mmu back on) */ + isync + + /* Get LR -- it points to the end of the exception vector code. We adjust it + to point to the beginning and can use it to identify the vector later. */ + mflr %r3 + subi %r3, %r3, 20 /* 5 instructions */ + + /* jump to kernel code (ppc_exception_tail) */ + lwz %r2, 0(%r1) + mtlr %r2 + blr + + +DEFINE_VECTOR(0x100, system_reset_exception) +DEFINE_VECTOR(0x200, machine_check_exception) +DEFINE_VECTOR(0x300, DSI_exception) +DEFINE_VECTOR(0x400, ISI_exception) +DEFINE_VECTOR(0x500, external_interrupt_exception) +DEFINE_VECTOR(0x600, alignment_exception) +DEFINE_VECTOR(0x700, program_exception) +DEFINE_VECTOR(0x800, FP_unavailable_exception) +DEFINE_VECTOR(0x900, decrementer_exception) +DEFINE_VECTOR(0xc00, system_call_exception) +DEFINE_VECTOR(0xd00, trace_exception) +DEFINE_VECTOR(0xe00, FP_assist_exception) +DEFINE_VECTOR(0xf00, perf_monitor_exception) +DEFINE_VECTOR(0xf20, altivec_unavailable_exception) +DEFINE_VECTOR(0x1000, ITLB_miss_exception) +DEFINE_VECTOR(0x1100, DTLB_miss_on_load_exception) +DEFINE_VECTOR(0x1200, DTLB_miss_on_store_exception) +DEFINE_VECTOR(0x1300, instruction_address_breakpoint_exception) +DEFINE_VECTOR(0x1400, system_management_exception) +DEFINE_VECTOR(0x1600, altivec_assist_exception) +DEFINE_VECTOR(0x1700, thermal_management_exception) + +.global __44x_irqvec_end +__44x_irqvec_end: + + +/* This is where ppc_44x_exception_vector_common continues. We're in the kernel here. + r1: ppc_cpu_exception_context* (virtual address) + r3: exception vector offset + SPRG1: original r1 + */ +FUNCTION(ppc_44x_exception_tail): + /* turn off BAT */ + li %r2, 0 + mtibatu 0, %r2 + mtibatl 0, %r2 + isync + sync + + /* save CR */ + mfcr %r0 + + mfsrr1 %r2 /* load saved msr */ + andi. %r2, %r2, (1 << 14) /* see if it was in kernel mode */ + beq .kernel /* yep */ + + /* We come from userland. Load the kernel stack top address for the current + userland thread. */ + mr %r2, %r1 + lwz %r1, 8(%r1) + b .restore_stack_end + +.kernel: + mr %r2, %r1 + mfsprg1 %r1 + +.restore_stack_end: + /* now r2 points to the ppc_cpu_exception_context, r1 to the kernel stack */ + /* restore the CR, it was messed up in the previous compare */ + mtcrf 0xff, %r0 + + /* align r1 to 8 bytes, so the iframe will be aligned too */ + rlwinm %r1, %r1, 0, 0, 28 + + /* save the registers */ + bl __44x_save_regs + + /* iframe pointer to r4 and a backup to r20 */ + mr %r4, %r1 + mr %r20, %r1 + + /* adjust the stack pointer for ABI compatibility */ + subi %r1, %r1, 8 /* make sure there's space for the previous + frame pointer and the return address */ + rlwinm %r1, %r1, 0, 0, 27 /* 16 byte align the stack pointer */ + li %r0, 0 + stw %r0, 0(%r1) /* previous frame pointer: NULL */ + /* 4(%r1) is room for the return address to be filled in by the + called function. */ + + /* r3: exception vector offset + r4: iframe pointer */ + bl ppc_exception_entry + + /* move the iframe to r1 */ + mr %r1, %r20 + + b __44x_restore_regs_and_rfi + + +/* called by ppc_44x_exception_tail + * register expectations: + * r1: stack + * r2: ppc_cpu_exception_context* + * SPRG1: original r1 + * r0,r3, LR: scrambled, but saved in scratch memory + * all other regs should have been unmodified by the exception handler, + * and ready to be saved + */ +__44x_save_regs: + /* Note: The iframe must be 8 byte aligned. The stack pointer we are passed + in r1 is aligned. So we store the floating point registers first and + need to take care that an even number of 4 byte registers is stored, + or insert padding respectively. */ + + /* push f0-f31 */ + stfdu %f0, -8(%r1) + stfdu %f1, -8(%r1) + stfdu %f2, -8(%r1) + stfdu %f3, -8(%r1) + stfdu %f4, -8(%r1) + stfdu %f5, -8(%r1) + stfdu %f6, -8(%r1) + stfdu %f7, -8(%r1) + stfdu %f8, -8(%r1) + stfdu %f9, -8(%r1) + stfdu %f10, -8(%r1) + stfdu %f11, -8(%r1) + stfdu %f12, -8(%r1) + stfdu %f13, -8(%r1) + stfdu %f14, -8(%r1) + stfdu %f15, -8(%r1) + stfdu %f16, -8(%r1) + stfdu %f17, -8(%r1) + stfdu %f18, -8(%r1) + stfdu %f19, -8(%r1) + stfdu %f20, -8(%r1) + stfdu %f21, -8(%r1) + stfdu %f22, -8(%r1) + stfdu %f23, -8(%r1) + stfdu %f24, -8(%r1) + stfdu %f25, -8(%r1) + stfdu %f26, -8(%r1) + stfdu %f27, -8(%r1) + stfdu %f28, -8(%r1) + stfdu %f29, -8(%r1) + stfdu %f30, -8(%r1) + stfdu %f31, -8(%r1) + + /* push r0-r3 */ + lwz %r0, 16(%r2) /* original r0 */ + stwu %r0, -4(%r1) /* push r0 */ + mfsprg1 %r0 /* original r1 */ + stwu %r0, -4(%r1) /* push r1 */ + lwz %r0, 24(%r2) /* original r2 */ + stwu %r0, -4(%r1) /* push r2 */ + lwz %r0, 28(%r2) /* original r3 */ + stwu %r0, -4(%r1) /* push r3 */ + + /* push r4-r31 */ + stwu %r4, -4(%r1) + stwu %r5, -4(%r1) + stwu %r6, -4(%r1) + stwu %r7, -4(%r1) + stwu %r8, -4(%r1) + stwu %r9, -4(%r1) + stwu %r10, -4(%r1) + stwu %r11, -4(%r1) + stwu %r12, -4(%r1) + stwu %r13, -4(%r1) + stwu %r14, -4(%r1) + stwu %r15, -4(%r1) + stwu %r16, -4(%r1) + stwu %r17, -4(%r1) + stwu %r18, -4(%r1) + stwu %r19, -4(%r1) + stwu %r20, -4(%r1) + stwu %r21, -4(%r1) + stwu %r22, -4(%r1) + stwu %r23, -4(%r1) + stwu %r24, -4(%r1) + stwu %r25, -4(%r1) + stwu %r26, -4(%r1) + stwu %r27, -4(%r1) + stwu %r28, -4(%r1) + stwu %r29, -4(%r1) + stwu %r30, -4(%r1) + stwu %r31, -4(%r1) + + /* save some of the other regs */ + mffs %f0 + stfsu %f0, -4(%r1) /* push FPSCR */ + mfctr %r0 + stwu %r0, -4(%r1) /* push CTR */ + mfxer %r0 + stwu %r0, -4(%r1) /* push XER */ + mfcr %r0 + stwu %r0, -4(%r1) /* push CR */ + lwz %r0, 20(%r2) /* original LR */ + stwu %r0, -4(%r1) /* push LR */ + mfspr %r0, %dsisr + stwu %r0, -4(%r1) /* push DSISR */ + mfspr %r0, %dar + stwu %r0, -4(%r1) /* push DAR */ + mfspr %r0, %srr1 + stwu %r0, -4(%r1) /* push SRR1 */ + mfspr %r0, %srr0 + stwu %r0, -4(%r1) /* push SRR0 */ + + stwu %r3, -4(%r1) /* exception vector offset */ + + blr + + +/* called at the tail end of each of the exceptions + * r1: iframe pointer + */ +__44x_restore_regs_and_rfi: + lwzu %r0, 4(%r1) /* SRR0 (skip vector offset) */ + mtspr %srr0, %r0 + lwzu %r0, 4(%r1) /* SRR1 */ + mtspr %srr1, %r0 + lwzu %r0, 4(%r1) /* DAR */ + mtspr %dar, %r0 + lwzu %r0, 4(%r1) /* DSISR */ + mtspr %dsisr, %r0 + lwzu %r0, 4(%r1) /* LR */ + mtlr %r0 + lwzu %r0, 4(%r1) /* CR */ + mtcr %r0 + lwzu %r0, 4(%r1) /* XER */ + mtxer %r0 + lwzu %r0, 4(%r1) /* CTR */ + mtctr %r0 + lfsu %f0, 4(%r1) /* FPSCR */ + mtfsf 0xff, %f0 + + lwzu %r31, 4(%r1) + lwzu %r30, 4(%r1) + lwzu %r29, 4(%r1) + lwzu %r28, 4(%r1) + lwzu %r27, 4(%r1) + lwzu %r26, 4(%r1) + lwzu %r25, 4(%r1) + lwzu %r24, 4(%r1) + lwzu %r23, 4(%r1) + lwzu %r22, 4(%r1) + lwzu %r21, 4(%r1) + lwzu %r20, 4(%r1) + lwzu %r19, 4(%r1) + lwzu %r18, 4(%r1) + lwzu %r17, 4(%r1) + lwzu %r16, 4(%r1) + lwzu %r15, 4(%r1) + lwzu %r14, 4(%r1) + lwzu %r13, 4(%r1) + lwzu %r12, 4(%r1) + lwzu %r11, 4(%r1) + lwzu %r10, 4(%r1) + lwzu %r9, 4(%r1) + lwzu %r8, 4(%r1) + lwzu %r7, 4(%r1) + lwzu %r6, 4(%r1) + lwzu %r5, 4(%r1) + lwzu %r4, 4(%r1) + lwzu %r3, 4(%r1) + + /* Stop here, before we overwrite r1, and continue with the floating point + registers first. */ + addi %r2, %r1, 16 /* skip r3-r0 */ + + /* f31-f0 */ + lfd %f31, 0(%r2) + lfdu %f30, 8(%r2) + lfdu %f29, 8(%r2) + lfdu %f28, 8(%r2) + lfdu %f27, 8(%r2) + lfdu %f26, 8(%r2) + lfdu %f25, 8(%r2) + lfdu %f24, 8(%r2) + lfdu %f23, 8(%r2) + lfdu %f22, 8(%r2) + lfdu %f21, 8(%r2) + lfdu %f20, 8(%r2) + lfdu %f19, 8(%r2) + lfdu %f18, 8(%r2) + lfdu %f17, 8(%r2) + lfdu %f16, 8(%r2) + lfdu %f15, 8(%r2) + lfdu %f14, 8(%r2) + lfdu %f13, 8(%r2) + lfdu %f12, 8(%r2) + lfdu %f11, 8(%r2) + lfdu %f10, 8(%r2) + lfdu %f9, 8(%r2) + lfdu %f8, 8(%r2) + lfdu %f7, 8(%r2) + lfdu %f6, 8(%r2) + lfdu %f5, 8(%r2) + lfdu %f4, 8(%r2) + lfdu %f3, 8(%r2) + lfdu %f2, 8(%r2) + lfdu %f1, 8(%r2) + lfd %f0, 8(%r2) + + /* r2-r0 */ + lwzu %r2, 4(%r1) + lwz %r0, 8(%r1) + lwz %r1, 4(%r1) + + /* return from interrupt */ + rfi From a442699e34c327687f0f6d0a4fc859bdcf5a6ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sat, 1 Jun 2013 19:32:43 +0200 Subject: [PATCH 049/137] PPC: Use asm_defs.h instead of hardcoded defines --- src/system/kernel/arch/ppc/arch_exceptions.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/system/kernel/arch/ppc/arch_exceptions.S b/src/system/kernel/arch/ppc/arch_exceptions.S index b20198d257..85e532dd1e 100644 --- a/src/system/kernel/arch/ppc/arch_exceptions.S +++ b/src/system/kernel/arch/ppc/arch_exceptions.S @@ -5,8 +5,7 @@ * Copyright 2003, Travis Geiselbrecht. All rights reserved. * Distributed under the terms of the NewOS License. */ -#define FUNCTION(x) .global x; .type x,@function; x -#define LOCAL_FUNCTION(x) .type x,@function; x +#include /* General exception handling concept: From b8dc812f3e99db27af1d4e6495a305bfb830a507 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Sat, 14 Sep 2013 05:25:56 +0200 Subject: [PATCH 050/137] x86[_64]: Enable NX on non-boot CPUs as soon as possible --- src/system/kernel/arch/x86/arch_cpu.cpp | 9 --------- .../arch/x86/paging/64bit/X86PagingMethod64Bit.cpp | 14 ++++++++++---- .../arch/x86/paging/pae/X86PagingMethodPAE.cpp | 12 ++++++++---- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index 67212e2e17..a817ec05b7 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -753,15 +753,6 @@ arch_cpu_init_percpu(kernel_args* args, int cpu) } } - // If availalbe enable NX-bit (No eXecute). Boot CPU can not enable - // NX-bit here since PAE should be enabled first. - if (cpu != 0) { - if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) { - x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) - | IA32_MSR_EFER_NX); - } - } - return B_OK; } diff --git a/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp b/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp index b560db08c8..2a6ef7986d 100644 --- a/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp +++ b/src/system/kernel/arch/x86/paging/64bit/X86PagingMethod64Bit.cpp @@ -60,10 +60,8 @@ X86PagingMethod64Bit::Init(kernel_args* args, fKernelVirtualPML4 = (uint64*)(addr_t)args->arch_args.vir_pgdir; // if availalbe enable NX-bit (No eXecute) - if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) { - x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) - | IA32_MSR_EFER_NX); - } + if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) + call_all_cpus_sync(&_EnableExecutionDisable, NULL); // Ensure that the user half of the address space is clear. This removes // the temporary identity mapping made by the boot loader. @@ -384,3 +382,11 @@ X86PagingMethod64Bit::PutPageTableEntryInTable(uint64* entry, SetTableEntry(entry, page); } + +/*static*/ void +X86PagingMethod64Bit::_EnableExecutionDisable(void* dummy, int cpu) +{ + x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) + | IA32_MSR_EFER_NX); +} + diff --git a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp index f8b471279d..6e1da996c2 100644 --- a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp +++ b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp @@ -149,10 +149,8 @@ struct X86PagingMethodPAE::ToPAESwitcher { call_all_cpus_sync(&_EnablePAE, (void*)(addr_t)physicalPDPT); // if availalbe enable NX-bit (No eXecute) - if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) { - x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) - | IA32_MSR_EFER_NX); - } + if (x86_check_feature(IA32_FEATURE_AMD_EXT_NX, FEATURE_EXT_AMD)) + call_all_cpus_sync(&_EnableExecutionDisable, NULL); // set return values _virtualPDPT = pdpt; @@ -173,6 +171,12 @@ private: x86_write_cr4(x86_read_cr4() | IA32_CR4_PAE | IA32_CR4_GLOBAL_PAGES); } + static void _EnableExecutionDisable(void* dummy, int cpu) + { + x86_write_msr(IA32_MSR_EFER, x86_read_msr(IA32_MSR_EFER) + | IA32_MSR_EFER_NX); + } + void _TranslatePageTable(addr_t virtualBase) { page_table_entry* entry = &fPageHole[virtualBase / B_PAGE_SIZE]; From aba841d81066e4dc39b6dd28fd4d13341b5db46f Mon Sep 17 00:00:00 2001 From: Niels Sascha Reedijk Date: Sat, 14 Sep 2013 06:14:01 +0200 Subject: [PATCH 051/137] Update translations from Pootle --- data/catalogs/apps/activitymonitor/fi.catkeys | 5 ++++- data/catalogs/apps/icon-o-matic/fr.catkeys | 4 +++- data/catalogs/kits/mail/fi.catkeys | 3 ++- data/catalogs/preferences/screensaver/be.catkeys | 4 +++- data/catalogs/preferences/screensaver/de.catkeys | 4 +++- data/catalogs/preferences/screensaver/fi.catkeys | 4 +++- data/catalogs/preferences/screensaver/fr.catkeys | 4 +++- data/catalogs/preferences/screensaver/hu.catkeys | 4 +++- data/catalogs/preferences/screensaver/ja.catkeys | 4 +++- 9 files changed, 27 insertions(+), 9 deletions(-) diff --git a/data/catalogs/apps/activitymonitor/fi.catkeys b/data/catalogs/apps/activitymonitor/fi.catkeys index eea09ea3e6..b1bc1b1fb5 100644 --- a/data/catalogs/apps/activitymonitor/fi.catkeys +++ b/data/catalogs/apps/activitymonitor/fi.catkeys @@ -1,4 +1,4 @@ -1 finnish x-vnd.Haiku-ActivityMonitor 2739021859 +1 finnish x-vnd.Haiku-ActivityMonitor 1211510241 P-faults DataSource P-viat Media nodes DataSource Mediasolmut Threads DataSource Säikeet @@ -6,6 +6,7 @@ Always on top ActivityWindow Aina päällimmäisenä Add graph ActivityWindow Lisää kuvaaja Teams DataSource Ryhmät Hide legend ActivityView Piilota merkin selitys +MiB DataSource mebitavua Network send DataSource Verkkolähetys CPU usage (combined) DataSource Suoritinkäyttö (yhdistetty) CPU DataSource Suoritin @@ -26,12 +27,14 @@ Update time interval: SettingsWindow Päivitä aikaväli: TX DataSource Shorter version for Sending Läh. Quit ActivityWindow Poistu Block cache memory DataSource Lohkovälimuisti +%.1f KiB/s DataSource %.1f kibitavua/s Remove graph ActivityView Poista kuvaaja %lld sec. SettingsWindow %lld s %lld ms SettingsWindow %lld ms CPU usage DataSource Suoritinkäyttö Raw clipboard DataSource Raakadataleikepöytä Sems DataSource Opastimet +%.1f MiB DataSource %.1f Mebitavua ActivityMonitor System name Aktiviteettivalvonta Running applications DataSource Suoritetaan sovelluksia Semaphores DataSource Opastimet diff --git a/data/catalogs/apps/icon-o-matic/fr.catkeys b/data/catalogs/apps/icon-o-matic/fr.catkeys index 6383f582f2..806631486e 100644 --- a/data/catalogs/apps/icon-o-matic/fr.catkeys +++ b/data/catalogs/apps/icon-o-matic/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.haiku-icon_o_matic 605140404 +1 french x-vnd.haiku-icon_o_matic 806315965 Select All Icon-O-Matic-PathManipulator Sélectionner tout Add Style Icon-O-Matic-AddStylesCmd Ajouter un style Color (#%02x%02x%02x) Style name after dropping a color Couleur (#%02x%02x%02x) @@ -67,6 +67,7 @@ Contour Transformation Contour Perspective Transformation Perspective Move Transformer Icon-O-Matic-MoveTransformersCmd Déplacer la Transformation Opacity Icon-O-Matic-PropertyNames Opacité +Add with path Icon-O-Matic-ShapesList Ajouter avec un chemin Gradient type Icon-O-Matic-StyleTypes Type de dégradé Icon-O-Matic System name Icon-O-Matic Cancel Icon-O-Matic-Menu-Settings Annuler @@ -79,6 +80,7 @@ META:ICON Attribute Icon-O-Matic-SavePanel Attribut META:ICON Translation Y Icon-O-Matic-PropertyNames Translation en Y Rotate Icon-O-Matic-TransformationBoxStates Pivoter Remove Transformer Icon-O-Matic-RemoveTransformersCmd Supprimer une transformation +Rotate Path Indices Icon-O-Matic-RotatePathIndiciesCmd Rotation des indices de chemin Add Transformer Icon-O-Matic-AddTransformersCmd Ajouter une transformation Remove Icon-O-Matic-PathsList Enlever Nudge Control Point Icon-O-Matic-NudgePointsCommand Déplacer le point de contrôle diff --git a/data/catalogs/kits/mail/fi.catkeys b/data/catalogs/kits/mail/fi.catkeys index da29589bc9..994a53ba36 100644 --- a/data/catalogs/kits/mail/fi.catkeys +++ b/data/catalogs/kits/mail/fi.catkeys @@ -1,7 +1,8 @@ -1 finnish x-vnd.Haiku-libmail 161731481 +1 finnish x-vnd.Haiku-libmail 4037525365 Partially download messages larger than ProtocolConfigView Osittain ladatut viestit suurempia kuin Password: ProtocolConfigView Salasana: Remove mail from server when deleted ProtocolConfigView Poista sähköposti palvelimelta poistettaessa +KiB ProtocolConfigView kibitavua Mail server: ProtocolConfigView Sähköpostipalvelin: Select… MailKit Valitse... Connection type: ProtocolConfigView Yhteystyyppi: diff --git a/data/catalogs/preferences/screensaver/be.catkeys b/data/catalogs/preferences/screensaver/be.catkeys index 48c4f84ac0..3925c11a48 100644 --- a/data/catalogs/preferences/screensaver/be.catkeys +++ b/data/catalogs/preferences/screensaver/be.catkeys @@ -1,4 +1,4 @@ -1 belarusian x-vnd.Haiku-ScreenSaver 3630119516 +1 belarusian x-vnd.Haiku-ScreenSaver 232492478 Could not load screen saver ScreenSaver Не ўдалося загрузіць захавальнік экрана 30 seconds ScreenSaver 30 секунд Start screensaver ScreenSaver Запусціць захавальнік @@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Кіраванне ScreenSaver System name Захавальнік Экрана Test ScreenSaver Тэст General ScreenSaver Агульныя +Fade now when mouse is here ScreenSaver Зацямняць перасунуўшы указальнік мышы сюды Enable screensaver ScreenSaver Уключыць захавальнік +Don't fade when mouse is here ScreenSaver Не зацямняць калі указальнік мышы знаходзіцца тут Cancel ScreenSaver Адмена Turn off screen ScreenSaver Выключыць экран No options available ScreenSaver Ніякія опцыі недаступныя diff --git a/data/catalogs/preferences/screensaver/de.catkeys b/data/catalogs/preferences/screensaver/de.catkeys index b039065d8a..a576ac2053 100644 --- a/data/catalogs/preferences/screensaver/de.catkeys +++ b/data/catalogs/preferences/screensaver/de.catkeys @@ -1,4 +1,4 @@ -1 german x-vnd.Haiku-ScreenSaver 3630119516 +1 german x-vnd.Haiku-ScreenSaver 232492478 Could not load screen saver ScreenSaver Bildschirmschoner konnte nicht geladen werden. 30 seconds ScreenSaver 30 Sekunden Start screensaver ScreenSaver Bildschirmschoner starten @@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Stromsparfunktione ScreenSaver System name Bildschirmschoner Test ScreenSaver Test General ScreenSaver Allgemein +Fade now when mouse is here ScreenSaver Sofort starten, wenn Maus in diesem Eck Enable screensaver ScreenSaver Bildschirmschoner aktivieren +Don't fade when mouse is here ScreenSaver Nicht starten, wenn Maus in diesem Eck Cancel ScreenSaver Abbrechen Turn off screen ScreenSaver Bildschirm ausschalten No options available ScreenSaver Keine Optionen verfügbar diff --git a/data/catalogs/preferences/screensaver/fi.catkeys b/data/catalogs/preferences/screensaver/fi.catkeys index 3aa51a0d98..f7a7179924 100644 --- a/data/catalogs/preferences/screensaver/fi.catkeys +++ b/data/catalogs/preferences/screensaver/fi.catkeys @@ -1,4 +1,4 @@ -1 finnish x-vnd.Haiku-ScreenSaver 3630119516 +1 finnish x-vnd.Haiku-ScreenSaver 232492478 Could not load screen saver ScreenSaver Näytönsäästäjän lataus epäonnistui 30 seconds ScreenSaver 30 sekuntia Start screensaver ScreenSaver Käynnistä näytönsäästäjä @@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Näytön jännites ScreenSaver System name Näytönsäästäjäasetukset Test ScreenSaver Testaa General ScreenSaver Yleinen +Fade now when mouse is here ScreenSaver Häivytä nyt kun hiiren kohdistin on tässä Enable screensaver ScreenSaver Ota käyttöön näytönsäästäjä +Don't fade when mouse is here ScreenSaver Älä häivytä, kun hiiren kohdistin on tässä Cancel ScreenSaver Peru Turn off screen ScreenSaver Käännä näyttö pois päältä No options available ScreenSaver Valitsimia ei ole käytettävissä diff --git a/data/catalogs/preferences/screensaver/fr.catkeys b/data/catalogs/preferences/screensaver/fr.catkeys index 46ae0944ad..630beaf17a 100644 --- a/data/catalogs/preferences/screensaver/fr.catkeys +++ b/data/catalogs/preferences/screensaver/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.Haiku-ScreenSaver 3630119516 +1 french x-vnd.Haiku-ScreenSaver 232492478 Could not load screen saver ScreenSaver Impossible de charger l'économiseur d'écran 30 seconds ScreenSaver 30 secondes Start screensaver ScreenSaver Démarrer l'économiseur @@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Le système d'éco ScreenSaver System name Économiseur d'écran Test ScreenSaver Tester General ScreenSaver Général +Fade now when mouse is here ScreenSaver Estomper maintenant lorsque la souris est ici Enable screensaver ScreenSaver Activer l'économiseur +Don't fade when mouse is here ScreenSaver Ne pas estomper lorsque la souris est ici Cancel ScreenSaver Annuler Turn off screen ScreenSaver Extinction de l'écran No options available ScreenSaver Aucune option disponible diff --git a/data/catalogs/preferences/screensaver/hu.catkeys b/data/catalogs/preferences/screensaver/hu.catkeys index ebb2c4e37f..a41a110074 100644 --- a/data/catalogs/preferences/screensaver/hu.catkeys +++ b/data/catalogs/preferences/screensaver/hu.catkeys @@ -1,4 +1,4 @@ -1 hungarian x-vnd.Haiku-ScreenSaver 3630119516 +1 hungarian x-vnd.Haiku-ScreenSaver 232492478 Could not load screen saver ScreenSaver A képernyővédő betöltése sikertelen 30 seconds ScreenSaver 30 másodperc Start screensaver ScreenSaver Képernyővédő indítása @@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver A kijelző energia ScreenSaver System name Képernyővédő Test ScreenSaver Próba General ScreenSaver Általános +Fade now when mouse is here ScreenSaver Bekapcsolás, ha az egér itt van Enable screensaver ScreenSaver Képernyővédő engedélyezése +Don't fade when mouse is here ScreenSaver Ne kapcsoljon be, ha az egér itt van Cancel ScreenSaver Mégse Turn off screen ScreenSaver Képernyő kikapcsolása No options available ScreenSaver Nincsenek elérhető beállítások diff --git a/data/catalogs/preferences/screensaver/ja.catkeys b/data/catalogs/preferences/screensaver/ja.catkeys index c247d6b182..c1a0c1d5fa 100644 --- a/data/catalogs/preferences/screensaver/ja.catkeys +++ b/data/catalogs/preferences/screensaver/ja.catkeys @@ -1,4 +1,4 @@ -1 japanese x-vnd.Haiku-ScreenSaver 3630119516 +1 japanese x-vnd.Haiku-ScreenSaver 232492478 Could not load screen saver ScreenSaver スクリーンセーバーを実行できませんでした 30 seconds ScreenSaver 30 秒 Start screensaver ScreenSaver スクリーンセーバーを開始 @@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver DPMS (Display Powe ScreenSaver System name スクリーンセーバー Test ScreenSaver テスト General ScreenSaver 一般 +Fade now when mouse is here ScreenSaver マウスが指定の場所にあるときに画面を消す Enable screensaver ScreenSaver スクリーンセーバーを有効にする +Don't fade when mouse is here ScreenSaver マウスが指定の場所にあるとき画面を消さない Cancel ScreenSaver 取り消し Turn off screen ScreenSaver 画面を消す No options available ScreenSaver 設定がありません From 0ce7ab1ebed17b2b1e23aa44868664535c7ab5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sat, 14 Sep 2013 11:00:07 +0200 Subject: [PATCH 052/137] ext2: access the parent variable once checked it's non null * cleanup * add some inode flags we don't use --- .../kernel/file_systems/ext2/Inode.cpp | 6 +-- src/add-ons/kernel/file_systems/ext2/ext2.h | 40 ++++++++++--------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/add-ons/kernel/file_systems/ext2/Inode.cpp b/src/add-ons/kernel/file_systems/ext2/Inode.cpp index 3a07a8c4c8..e8a1529ba0 100644 --- a/src/add-ons/kernel/file_systems/ext2/Inode.cpp +++ b/src/add-ons/kernel/file_systems/ext2/Inode.cpp @@ -633,8 +633,9 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name, inode->SetAccessTime(×pec); inode->SetCreationTime(×pec); inode->SetModificationTime(×pec); - node.SetFlags(parent->Flags() & EXT2_INODE_INHERITED); - if (volume->HasExtentsFeature() + if (parent != NULL) + node.SetFlags(parent->Flags() & EXT2_INODE_INHERITED); + if (volume->HasExtentsFeature() && (inode->IsDirectory() || inode->IsFile())) { node.SetFlag(EXT2_INODE_EXTENTS); ExtentStream stream(volume, &node.extent_stream, 0); @@ -935,4 +936,3 @@ Inode::IncrementNumLinks(Transaction& transaction) fVolume->ActivateDirNLink(transaction); } } - diff --git a/src/add-ons/kernel/file_systems/ext2/ext2.h b/src/add-ons/kernel/file_systems/ext2/ext2.h index b966e7c72d..2bc5f7fc29 100644 --- a/src/add-ons/kernel/file_systems/ext2/ext2.h +++ b/src/add-ons/kernel/file_systems/ext2/ext2.h @@ -141,13 +141,13 @@ struct ext2_super_block { { free_blocks = B_HOST_TO_LENDIAN_INT32(freeBlocks & 0xffffffff); if (has64bits) - free_blocks_high = B_HOST_TO_LENDIAN_INT32(freeBlocks >> 32); + free_blocks_high = B_HOST_TO_LENDIAN_INT32(freeBlocks >> 32); } void SetLastOrphan(ino_t id) { last_orphan = B_HOST_TO_LENDIAN_INT32((uint32)id); } void SetReadOnlyFeatures(uint32 readOnlyFeatures) const { readOnlyFeatures = B_HOST_TO_LENDIAN_INT32(readOnlyFeatures); } - + bool IsValid(); // implemented in Volume.cpp } _PACKED; @@ -211,7 +211,7 @@ struct ext2_block_group { uint32 _reserved[2]; uint16 unused_inodes; uint16 checksum; - + // ext4 uint32 block_bitmap_high; uint32 inode_bitmap_high; @@ -249,7 +249,7 @@ struct ext2_block_group { { uint32 blocks = B_LENDIAN_TO_HOST_INT16(free_blocks); if (has64bits) - blocks |= + blocks |= ((uint32)B_LENDIAN_TO_HOST_INT16(free_blocks_high) << 16); return blocks; } @@ -257,7 +257,7 @@ struct ext2_block_group { { uint32 inodes = B_LENDIAN_TO_HOST_INT16(free_inodes); if (has64bits) - inodes |= + inodes |= ((uint32)B_LENDIAN_TO_HOST_INT16(free_inodes_high) << 16); return inodes; } @@ -265,7 +265,7 @@ struct ext2_block_group { { uint32 dirs = B_LENDIAN_TO_HOST_INT16(used_directories); if (has64bits) - dirs |= + dirs |= ((uint32)B_LENDIAN_TO_HOST_INT16(used_directories_high) << 16); return dirs; } @@ -274,11 +274,11 @@ struct ext2_block_group { { uint32 inodes = B_LENDIAN_TO_HOST_INT16(unused_inodes); if (has64bits) - inodes |= + inodes |= ((uint32)B_LENDIAN_TO_HOST_INT16(unused_inodes_high) << 16); return inodes; } - + void SetFreeBlocks(uint32 freeBlocks, bool has64bits) { @@ -376,7 +376,7 @@ struct ext2_extent_entry { uint32 physical_block; uint32 LogicalBlock() const { return B_LENDIAN_TO_HOST_INT32(logical_block); } - uint16 Length() const { return B_LENDIAN_TO_HOST_INT16(length) == 0x8000 + uint16 Length() const { return B_LENDIAN_TO_HOST_INT16(length) == 0x8000 ? 0x8000 : B_LENDIAN_TO_HOST_INT16(length) & 0x7fff; } uint64 PhysicalBlock() const { return B_LENDIAN_TO_HOST_INT32(physical_block) | ((uint64)B_LENDIAN_TO_HOST_INT16(physical_block_high) << 32); } @@ -437,7 +437,7 @@ struct ext2_inode { uint16 uid_high; uint16 gid_high; uint32 _reserved2; - + // extra attributes uint16 extra_inode_size; uint16 _padding2; @@ -460,18 +460,18 @@ struct ext2_inode { { timespec->tv_sec = B_LENDIAN_TO_HOST_INT32(time); if (extra && sizeof(timespec->tv_sec) > 4) - timespec->tv_sec |= + timespec->tv_sec |= (uint64)(B_LENDIAN_TO_HOST_INT32(time_extra) & 0x2) << 32; if (extra) timespec->tv_nsec = B_LENDIAN_TO_HOST_INT32(time_extra) >> 2; else timespec->tv_nsec = 0; } - - void GetModificationTime(struct timespec *timespec, bool extra) const - { _DecodeTime(timespec, modification_time, modification_time_extra, + + void GetModificationTime(struct timespec *timespec, bool extra) const + { _DecodeTime(timespec, modification_time, modification_time_extra, extra); } - void GetAccessTime(struct timespec *timespec, bool extra) const + void GetAccessTime(struct timespec *timespec, bool extra) const { _DecodeTime(timespec, access_time, access_time_extra, extra); } void GetChangeTime(struct timespec *timespec, bool extra) const { _DecodeTime(timespec, change_time, change_time_extra, extra); } @@ -494,7 +494,7 @@ struct ext2_inode { time |= (uint64)timespec->tv_sec >> 32; return B_HOST_TO_LENDIAN_INT32(time); } - + void SetModificationTime(const struct timespec *timespec, bool extra) { modification_time = B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_sec); @@ -517,7 +517,7 @@ struct ext2_inode { { if (extra) { creation_time = B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_sec); - creation_time_extra = + creation_time_extra = B_HOST_TO_LENDIAN_INT32((uint32)timespec->tv_nsec); } } @@ -527,7 +527,7 @@ struct ext2_inode { } ino_t NextOrphan() const { return (ino_t)DeletionTime(); } - + off_t Size() const { if (S_ISREG(Mode())) { @@ -654,6 +654,10 @@ struct ext2_inode { #define EXT2_INODE_DIR_SYNCH 0x00010000 #define EXT2_INODE_HUGE_FILE 0x00040000 #define EXT2_INODE_EXTENTS 0x00080000 +#define EXT2_INODE_LARGE_EA 0x00200000 +#define EXT2_INODE_EOF_BLOCKS 0x00400000 +#define EXT2_INODE_INLINE_DATA 0x10000000 +#define EXT2_INODE_RESERVED 0x80000000 #define EXT2_INODE_INHERITED (EXT2_INODE_SECURE_DELETION | EXT2_INODE_UNDELETE \ | EXT2_INODE_COMPRESSED | EXT2_INODE_SYNCHRONOUS | EXT2_INODE_IMMUTABLE \ From b5082c11ccf6875056602a934e02c73a9ed1fa71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sat, 14 Sep 2013 11:48:37 +0200 Subject: [PATCH 053/137] virtio_net: initial skeleton driver. --- src/add-ons/kernel/drivers/network/Jamfile | 1 + .../kernel/drivers/network/virtio/Jamfile | 8 + .../drivers/network/virtio/virtio_net.cpp | 317 ++++++++++++++++++ .../drivers/network/virtio/virtio_net.h | 202 +++++++++++ 4 files changed, 528 insertions(+) create mode 100644 src/add-ons/kernel/drivers/network/virtio/Jamfile create mode 100644 src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp create mode 100644 src/add-ons/kernel/drivers/network/virtio/virtio_net.h diff --git a/src/add-ons/kernel/drivers/network/Jamfile b/src/add-ons/kernel/drivers/network/Jamfile index 2940c7eb1e..224ba0c195 100644 --- a/src/add-ons/kernel/drivers/network/Jamfile +++ b/src/add-ons/kernel/drivers/network/Jamfile @@ -9,6 +9,7 @@ SubInclude HAIKU_TOP src add-ons kernel drivers network usb_asix ; SubInclude HAIKU_TOP src add-ons kernel drivers network usb_davicom ; SubInclude HAIKU_TOP src add-ons kernel drivers network usb_ecm ; SubInclude HAIKU_TOP src add-ons kernel drivers network via_rhine ; +SubInclude HAIKU_TOP src add-ons kernel drivers network virtio ; SubInclude HAIKU_TOP src add-ons kernel drivers network vlance ; SubInclude HAIKU_TOP src add-ons kernel drivers network wb840 ; diff --git a/src/add-ons/kernel/drivers/network/virtio/Jamfile b/src/add-ons/kernel/drivers/network/virtio/Jamfile new file mode 100644 index 0000000000..f8131115f2 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/virtio/Jamfile @@ -0,0 +1,8 @@ +SubDir HAIKU_TOP src add-ons kernel drivers network virtio ; + +UsePrivateKernelHeaders ; +UsePrivateHeaders drivers net virtio ; + +KernelAddon virtio_net : + virtio_net.cpp +; diff --git a/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp b/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp new file mode 100644 index 0000000000..92801feadf --- /dev/null +++ b/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp @@ -0,0 +1,317 @@ +/* + * Copyright 2013, Jérôme Duval, korli@users.berlios.de. + * Distributed under the terms of the MIT License. + */ + + +#include +#include + +#define ETHER_ADDR_LEN ETHER_ADDRESS_LENGTH +#include "virtio_net.h" + + + +#define VIRTIO_NET_DRIVER_MODULE_NAME "drivers/network/virtio_net/driver_v1" +#define VIRTIO_NET_DEVICE_MODULE_NAME "drivers/network/virtio_net/device_v1" +#define VIRTIO_NET_DEVICE_ID_GENERATOR "virtio_net/device_id" + + +typedef struct { + device_node* node; + ::virtio_device virtio_device; + virtio_device_interface* virtio; + + uint32 features; + +} virtio_net_driver_info; + + +typedef struct { + virtio_net_driver_info* info; +} virtio_net_handle; + + +#include +#include +#include + +#include + + +#define TRACE_VIRTIO_NET +#ifdef TRACE_VIRTIO_NET +# define TRACE(x...) dprintf("virtio_net: " x) +#else +# define TRACE(x...) ; +#endif +#define ERROR(x...) dprintf("\33[33mvirtio_net:\33[0m " x) +#define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__) + + +static device_manager_info* sDeviceManager; + + +const char * +get_feature_name(uint32 feature) +{ + switch (feature) { + } + return NULL; +} + + +// #pragma mark - device module API + + +static status_t +virtio_net_init_device(void* _info, void** _cookie) +{ + CALLED(); + virtio_net_driver_info* info = (virtio_net_driver_info*)_info; + + device_node* parent = sDeviceManager->get_parent_node(info->node); + sDeviceManager->get_driver(parent, (driver_module_info **)&info->virtio, + (void **)&info->virtio_device); + sDeviceManager->put_node(parent); + + info->virtio->negociate_features(info->virtio_device, + 0, &info->features, &get_feature_name); + + // TODO read config + // TODO alloc queues and setup interrupts + + *_cookie = info; + return B_OK; +} + + +static void +virtio_net_uninit_device(void* _cookie) +{ + CALLED(); + virtio_net_driver_info* info = (virtio_net_driver_info*)_cookie; +} + + +static status_t +virtio_net_open(void* _info, const char* path, int openMode, void** _cookie) +{ + CALLED(); + virtio_net_driver_info* info = (virtio_net_driver_info*)_info; + + virtio_net_handle* handle = (virtio_net_handle*)malloc( + sizeof(virtio_net_handle)); + if (handle == NULL) + return B_NO_MEMORY; + + handle->info = info; + + *_cookie = handle; + return B_OK; +} + + +static status_t +virtio_net_close(void* cookie) +{ + //virtio_net_handle* handle = (virtio_net_handle*)cookie; + CALLED(); + + return B_OK; +} + + +static status_t +virtio_net_free(void* cookie) +{ + CALLED(); + virtio_net_handle* handle = (virtio_net_handle*)cookie; + + free(handle); + return B_OK; +} + + +static status_t +virtio_net_read(void* cookie, off_t pos, void* buffer, size_t* _length) +{ + CALLED(); + virtio_net_handle* handle = (virtio_net_handle*)cookie; + // TODO implement + return B_ERROR; +} + + +static status_t +virtio_net_write(void* cookie, off_t pos, const void* buffer, + size_t* _length) +{ + CALLED(); + virtio_net_handle* handle = (virtio_net_handle*)cookie; + // TODO implement + return B_ERROR; +} + + +static status_t +virtio_net_ioctl(void* cookie, uint32 op, void* buffer, size_t length) +{ + CALLED(); + virtio_net_handle* handle = (virtio_net_handle*)cookie; + virtio_net_driver_info* info = handle->info; + + TRACE("ioctl(op = %ld)\n", op); + + switch (op) { + } + + return B_DEV_INVALID_IOCTL; +} + + +// #pragma mark - driver module API + + +static float +virtio_net_supports_device(device_node *parent) +{ + CALLED(); + const char *bus; + uint16 deviceType; + + // make sure parent is really the Virtio bus manager + if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) + return -1; + + if (strcmp(bus, "virtio")) + return 0.0; + + // check whether it's really a Direct Access Device + if (sDeviceManager->get_attr_uint16(parent, VIRTIO_DEVICE_TYPE_ITEM, + &deviceType, true) != B_OK || deviceType != VIRTIO_DEVICE_ID_NETWORK) + return 0.0; + + TRACE("Virtio network device found!\n"); + + return 0.6; +} + + +static status_t +virtio_net_register_device(device_node *node) +{ + CALLED(); + + // ready to register + device_attr attrs[] = { + { NULL } + }; + + return sDeviceManager->register_node(node, VIRTIO_NET_DRIVER_MODULE_NAME, + attrs, NULL, NULL); +} + + +static status_t +virtio_net_init_driver(device_node *node, void **cookie) +{ + CALLED(); + + virtio_net_driver_info* info = (virtio_net_driver_info*)malloc( + sizeof(virtio_net_driver_info)); + if (info == NULL) + return B_NO_MEMORY; + + memset(info, 0, sizeof(*info)); + + info->node = node; + + *cookie = info; + return B_OK; +} + + +static void +virtio_net_uninit_driver(void *_cookie) +{ + CALLED(); + virtio_net_driver_info* info = (virtio_net_driver_info*)_cookie; + free(info); +} + + +static status_t +virtio_net_register_child_devices(void* _cookie) +{ + CALLED(); + virtio_net_driver_info* info = (virtio_net_driver_info*)_cookie; + status_t status; + + int32 id = sDeviceManager->create_id(VIRTIO_NET_DEVICE_ID_GENERATOR); + if (id < 0) + return id; + + char name[64]; + snprintf(name, sizeof(name), "net/virtio/%" B_PRId32, + id); + + status = sDeviceManager->publish_device(info->node, name, + VIRTIO_NET_DEVICE_MODULE_NAME); + + return status; +} + + +// #pragma mark - + + +module_dependency module_dependencies[] = { + {B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&sDeviceManager}, + {} +}; + +struct device_module_info sVirtioNetDevice = { + { + VIRTIO_NET_DEVICE_MODULE_NAME, + 0, + NULL + }, + + virtio_net_init_device, + virtio_net_uninit_device, + NULL, // remove, + + virtio_net_open, + virtio_net_close, + virtio_net_free, + virtio_net_read, + virtio_net_write, + NULL, // io + virtio_net_ioctl, + + NULL, // select + NULL, // deselect +}; + +struct driver_module_info sVirtioNetDriver = { + { + VIRTIO_NET_DRIVER_MODULE_NAME, + 0, + NULL + }, + + virtio_net_supports_device, + virtio_net_register_device, + virtio_net_init_driver, + virtio_net_uninit_driver, + virtio_net_register_child_devices, + NULL, // rescan + NULL, // removed +}; + +module_info* modules[] = { + (module_info*)&sVirtioNetDriver, + (module_info*)&sVirtioNetDevice, + NULL +}; diff --git a/src/add-ons/kernel/drivers/network/virtio/virtio_net.h b/src/add-ons/kernel/drivers/network/virtio/virtio_net.h new file mode 100644 index 0000000000..315b730006 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/virtio/virtio_net.h @@ -0,0 +1,202 @@ +/*- + * This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _VIRTIO_NET_H +#define _VIRTIO_NET_H + +/* The feature bitmap for virtio net */ +#define VIRTIO_NET_F_CSUM 0x00001 /* Host handles pkts w/ partial csum */ +#define VIRTIO_NET_F_GUEST_CSUM 0x00002 /* Guest handles pkts w/ partial csum*/ +#define VIRTIO_NET_F_MAC 0x00020 /* Host has given MAC address. */ +#define VIRTIO_NET_F_GSO 0x00040 /* Host handles pkts w/ any GSO type */ +#define VIRTIO_NET_F_GUEST_TSO4 0x00080 /* Guest can handle TSOv4 in. */ +#define VIRTIO_NET_F_GUEST_TSO6 0x00100 /* Guest can handle TSOv6 in. */ +#define VIRTIO_NET_F_GUEST_ECN 0x00200 /* Guest can handle TSO[6] w/ ECN in.*/ +#define VIRTIO_NET_F_GUEST_UFO 0x00400 /* Guest can handle UFO in. */ +#define VIRTIO_NET_F_HOST_TSO4 0x00800 /* Host can handle TSOv4 in. */ +#define VIRTIO_NET_F_HOST_TSO6 0x01000 /* Host can handle TSOv6 in. */ +#define VIRTIO_NET_F_HOST_ECN 0x02000 /* Host can handle TSO[6] w/ ECN in. */ +#define VIRTIO_NET_F_HOST_UFO 0x04000 /* Host can handle UFO in. */ +#define VIRTIO_NET_F_MRG_RXBUF 0x08000 /* Host can merge receive buffers. */ +#define VIRTIO_NET_F_STATUS 0x10000 /* virtio_net_config.status available*/ +#define VIRTIO_NET_F_CTRL_VQ 0x20000 /* Control channel available */ +#define VIRTIO_NET_F_CTRL_RX 0x40000 /* Control channel RX mode support */ +#define VIRTIO_NET_F_CTRL_VLAN 0x80000 /* Control channel VLAN filtering */ +#define VIRTIO_NET_F_CTRL_RX_EXTRA 0x100000 /* Extra RX mode control support */ +#define VIRTIO_NET_F_GUEST_ANNOUNCE 0x200000 /* Announce device on network */ +#define VIRTIO_NET_F_MQ 0x400000 /* Device supports RFS */ +#define VIRTIO_NET_F_CTRL_MAC_ADDR 0x800000 /* Set MAC address */ + +#define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ + +struct virtio_net_config { + /* The config defining mac address (if VIRTIO_NET_F_MAC) */ + uint8_t mac[ETHER_ADDR_LEN]; + /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */ + uint16_t status; + /* Maximum number of each of transmit and receive queues; + * see VIRTIO_NET_F_MQ and VIRTIO_NET_CTRL_MQ. + * Legal values are between 1 and 0x8000. + */ + uint16_t max_virtqueue_pairs; +} _PACKED; + +/* + * This is the first element of the scatter-gather list. If you don't + * specify GSO or CSUM features, you can simply ignore the header. + */ +struct virtio_net_hdr { +#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 /* Use csum_start,csum_offset*/ +#define VIRTIO_NET_HDR_F_DATA_VALID 2 /* Csum is valid */ + uint8_t flags; +#define VIRTIO_NET_HDR_GSO_NONE 0 /* Not a GSO frame */ +#define VIRTIO_NET_HDR_GSO_TCPV4 1 /* GSO frame, IPv4 TCP (TSO) */ +#define VIRTIO_NET_HDR_GSO_UDP 3 /* GSO frame, IPv4 UDP (UFO) */ +#define VIRTIO_NET_HDR_GSO_TCPV6 4 /* GSO frame, IPv6 TCP */ +#define VIRTIO_NET_HDR_GSO_ECN 0x80 /* TCP has ECN set */ + uint8_t gso_type; + uint16_t hdr_len; /* Ethernet + IP + tcp/udp hdrs */ + uint16_t gso_size; /* Bytes to append to hdr_len per frame */ + uint16_t csum_start; /* Position to start checksumming from */ + uint16_t csum_offset; /* Offset after that to place checksum */ +}; + +/* + * This is the version of the header to use when the MRG_RXBUF + * feature has been negotiated. + */ +struct virtio_net_hdr_mrg_rxbuf { + struct virtio_net_hdr hdr; + uint16_t num_buffers; /* Number of merged rx buffers */ +}; + +/* + * Control virtqueue data structures + * + * The control virtqueue expects a header in the first sg entry + * and an ack/status response in the last entry. Data for the + * command goes in between. + */ +struct virtio_net_ctrl_hdr { + uint8_t net_class; // was renamed from class for c++ + uint8_t cmd; +} _PACKED; + +#define VIRTIO_NET_OK 0 +#define VIRTIO_NET_ERR 1 + +/* + * Control the RX mode, ie. promiscuous, allmulti, etc... + * All commands require an "out" sg entry containing a 1 byte + * state value, zero = disable, non-zero = enable. Commands + * 0 and 1 are supported with the VIRTIO_NET_F_CTRL_RX feature. + * Commands 2-5 are added with VIRTIO_NET_F_CTRL_RX_EXTRA. + */ +#define VIRTIO_NET_CTRL_RX 0 +#define VIRTIO_NET_CTRL_RX_PROMISC 0 +#define VIRTIO_NET_CTRL_RX_ALLMULTI 1 +#define VIRTIO_NET_CTRL_RX_ALLUNI 2 +#define VIRTIO_NET_CTRL_RX_NOMULTI 3 +#define VIRTIO_NET_CTRL_RX_NOUNI 4 +#define VIRTIO_NET_CTRL_RX_NOBCAST 5 + +/* + * Control the MAC filter table. + * + * The MAC filter table is managed by the hypervisor, the guest should + * assume the size is infinite. Filtering should be considered + * non-perfect, ie. based on hypervisor resources, the guest may + * received packets from sources not specified in the filter list. + * + * In addition to the class/cmd header, the TABLE_SET command requires + * two out scatterlists. Each contains a 4 byte count of entries followed + * by a concatenated byte stream of the ETH_ALEN MAC addresses. The + * first sg list contains unicast addresses, the second is for multicast. + * This functionality is present if the VIRTIO_NET_F_CTRL_RX feature + * is available. + * + * The ADDR_SET command requests one out scatterlist, it contains a + * 6 bytes MAC address. This functionality is present if the + * VIRTIO_NET_F_CTRL_MAC_ADDR feature is available. + */ +struct virtio_net_ctrl_mac { + uint32_t entries; + uint8_t macs[][ETHER_ADDR_LEN]; +} _PACKED; + +#define VIRTIO_NET_CTRL_MAC 1 +#define VIRTIO_NET_CTRL_MAC_TABLE_SET 0 +#define VIRTIO_NET_CTRL_MAC_ADDR_SET 1 + +/* + * Control VLAN filtering + * + * The VLAN filter table is controlled via a simple ADD/DEL interface. + * VLAN IDs not added may be filtered by the hypervisor. Del is the + * opposite of add. Both commands expect an out entry containing a 2 + * byte VLAN ID. VLAN filtering is available with the + * VIRTIO_NET_F_CTRL_VLAN feature bit. + */ +#define VIRTIO_NET_CTRL_VLAN 2 +#define VIRTIO_NET_CTRL_VLAN_ADD 0 +#define VIRTIO_NET_CTRL_VLAN_DEL 1 + +/* + * Control link announce acknowledgement + * + * The command VIRTIO_NET_CTRL_ANNOUNCE_ACK is used to indicate that + * driver has recevied the notification; device would clear the + * VIRTIO_NET_S_ANNOUNCE bit in the status field after it receives + * this command. + */ +#define VIRTIO_NET_CTRL_ANNOUNCE 3 +#define VIRTIO_NET_CTRL_ANNOUNCE_ACK 0 + +/* + * Control Receive Flow Steering + * + * The command VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET enables Receive Flow + * Steering, specifying the number of the transmit and receive queues + * that will be used. After the command is consumed and acked by the + * device, the device will not steer new packets on receive virtqueues + * other than specified nor read from transmit virtqueues other than + * specified. Accordingly, driver should not transmit new packets on + * virtqueues other than specified. + */ +struct virtio_net_ctrl_mq { + uint16_t virtqueue_pairs; +} _PACKED; + +#define VIRTIO_NET_CTRL_MQ 4 +#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET 0 +#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1 +#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000 + +#endif /* _VIRTIO_NET_H */ From 74e89b3446edc07dbede8abe626e78f4220abb8e Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sat, 14 Sep 2013 17:07:55 +0200 Subject: [PATCH 054/137] Fix accidentally truncated addresses in call frame unwind. --- src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp b/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp index 0922808fc1..73bd4a5651 100644 --- a/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp +++ b/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp @@ -315,8 +315,8 @@ ArchitectureX8664::CreateStackFrame(Image* image, FunctionDebugInfo* function, // The syscall stubs are frameless, the return address is on top of the // stack. - uint32 rsp = cpuState->IntRegisterValue(X86_64_REGISTER_RSP); - uint32 address; + uint64 rsp = cpuState->IntRegisterValue(X86_64_REGISTER_RSP); + uint64 address; if (fTeamMemory->ReadMemory(rsp, &address, 8) == 8) { returnAddress = address; previousFramePointer = framePointer; From fda9d308e1d9164720c0e7ecaff1ca20b80500fb Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Sat, 14 Sep 2013 17:23:04 +0200 Subject: [PATCH 055/137] ARM: kernel: Fix compilation issue with new gas. Turns out the new gas does not like spaces :( --- src/system/kernel/arch/arm/arch_asm.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/system/kernel/arch/arm/arch_asm.S b/src/system/kernel/arch/arm/arch_asm.S index eb570a5f90..689f615646 100644 --- a/src/system/kernel/arch/arm/arch_asm.S +++ b/src/system/kernel/arch/arm/arch_asm.S @@ -227,8 +227,8 @@ FUNCTION(arch_debug_call_with_fault_handler): // Set fault handler address, and fault handler stack pointer address. We // don't need to save the previous values, since that's done by the caller. ldr r4, =1f - str r4, [ r0, #CPU_ENT_fault_handler ] - str sp, [ r0, #CPU_ENT_fault_handler_stack_pointer ] + str r4, [r0, #CPU_ENT_fault_handler] + str sp, [r0, #CPU_ENT_fault_handler_stack_pointer] mov r4, r1 // call the function From 20c5fc4aa6dbafde619c385e912d41ea6d847527 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sat, 14 Sep 2013 17:46:00 +0200 Subject: [PATCH 056/137] Debugger: Add missing std::nothrow. --- .../debugger/user_interface/gui/team_window/VariablesView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp index 113c6cb8f4..b3cd434ef0 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -2103,7 +2103,7 @@ status_t VariablesView::_AddContextAction(const char* action, uint32 what, ContextActionList* actions, BMessage*& _message) { - _message = new BMessage(what); + _message = new(std::nothrow) BMessage(what); if (_message == NULL) return B_NO_MEMORY; From 729075a5e84fa7241e6d702348ae3f5fa80eef8a Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sat, 14 Sep 2013 17:53:54 +0200 Subject: [PATCH 057/137] Debugger: add Inspect context item to Registers view. - Allows one to treat the value of a register as a memory address and jump directly to inspecting said address. --- .../gui/team_window/RegistersView.cpp | 49 ++++++++++++++++++- .../gui/team_window/RegistersView.h | 5 ++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp b/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp index 239b6f5738..031bb6ba9b 100644 --- a/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -11,12 +11,17 @@ #include #include +#include +#include +#include #include "table/TableColumns.h" #include "Architecture.h" +#include "AutoDeleter.h" #include "CpuState.h" #include "GuiSettingsUtils.h" +#include "MessageCodes.h" #include "Register.h" #include "UiUtils.h" @@ -229,6 +234,48 @@ RegistersView::TableRowInvoked(Table* table, int32 rowIndex) } +void +RegistersView::TableCellMouseDown(Table* table, int32 rowIndex, + int32 columnIndex, BPoint screenWhere, uint32 buttons) +{ + if ((buttons & B_SECONDARY_MOUSE_BUTTON) == 0) + return; + + BVariant value; + if (!fRegisterTableModel->GetValueAt(rowIndex, columnIndex, value)) + return; + + BPopUpMenu* menu = new(std::nothrow)BPopUpMenu("Options"); + if (menu == NULL) + return; + + ObjectDeleter menuDeleter(menu); + BMessage* message = new(std::nothrow)BMessage(MSG_SHOW_INSPECTOR_WINDOW); + if (message == NULL) + return; + + message->AddUInt64("address", value.ToUInt64()); + + ObjectDeleter messageDeleter(message); + BMenuItem* item = new(std::nothrow)BMenuItem("Inspect", message); + if (item == NULL) + return; + + messageDeleter.Detach(); + ObjectDeleter itemDeleter(item); + if (!menu->AddItem(item)) + return; + + itemDeleter.Detach(); + menu->SetTargetForItems(Window()); + menuDeleter.Detach(); + + BRect mouseRect(screenWhere, screenWhere); + mouseRect.InsetBy(-4.0, -4.0); + menu->Go(screenWhere, true, false, mouseRect, true); +} + + void RegistersView::_Init() { diff --git a/src/apps/debugger/user_interface/gui/team_window/RegistersView.h b/src/apps/debugger/user_interface/gui/team_window/RegistersView.h index 8c680928c8..e3c0b27e4f 100644 --- a/src/apps/debugger/user_interface/gui/team_window/RegistersView.h +++ b/src/apps/debugger/user_interface/gui/team_window/RegistersView.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef REGISTERS_VIEW_H @@ -35,6 +36,10 @@ private: // TableListener virtual void TableRowInvoked(Table* table, int32 rowIndex); + virtual void TableCellMouseDown(Table* table, int32 rowIndex, + int32 columnIndex, BPoint screenWhere, + uint32 buttons); + void _Init(); private: From d0382396699fc5ac09035531f318e8f10b978612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sat, 14 Sep 2013 15:37:24 +0200 Subject: [PATCH 058/137] virtio_net: add feature labels. --- .../drivers/network/virtio/virtio_net.cpp | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp b/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp index 92801feadf..1c9fe19866 100644 --- a/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp +++ b/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp @@ -56,6 +56,48 @@ const char * get_feature_name(uint32 feature) { switch (feature) { + case VIRTIO_NET_F_CSUM: + return "host checksum"; + case VIRTIO_NET_F_GUEST_CSUM: + return "guest checksum"; + case VIRTIO_NET_F_MAC: + return "macaddress"; + case VIRTIO_NET_F_GSO: + return "host allgso"; + case VIRTIO_NET_F_GUEST_TSO4: + return "guest tso4"; + case VIRTIO_NET_F_GUEST_TSO6: + return "guest tso6"; + case VIRTIO_NET_F_GUEST_ECN: + return "guest tso6+ecn"; + case VIRTIO_NET_F_GUEST_UFO: + return "guest ufo"; + case VIRTIO_NET_F_HOST_TSO4: + return "host tso4"; + case VIRTIO_NET_F_HOST_TSO6: + return "host tso6"; + case VIRTIO_NET_F_HOST_ECN: + return "host tso6+ecn"; + case VIRTIO_NET_F_HOST_UFO: + return "host UFO"; + case VIRTIO_NET_F_MRG_RXBUF: + return "host mergerxbuffers"; + case VIRTIO_NET_F_STATUS: + return "status"; + case VIRTIO_NET_F_CTRL_VQ: + return "control vq"; + case VIRTIO_NET_F_CTRL_RX: + return "rx mode"; + case VIRTIO_NET_F_CTRL_VLAN: + return "vlan filter"; + case VIRTIO_NET_F_CTRL_RX_EXTRA: + return "rx mode extra"; + case VIRTIO_NET_F_GUEST_ANNOUNCE: + return "guest announce"; + case VIRTIO_NET_F_MQ: + return "multiqueue"; + case VIRTIO_NET_F_CTRL_MAC_ADDR: + return "set macaddress"; } return NULL; } @@ -76,7 +118,7 @@ virtio_net_init_device(void* _info, void** _cookie) sDeviceManager->put_node(parent); info->virtio->negociate_features(info->virtio_device, - 0, &info->features, &get_feature_name); + 0 /* */, &info->features, &get_feature_name); // TODO read config // TODO alloc queues and setup interrupts From 4b308f30cad12d676d43b20ffd80e7941a67dd45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sat, 14 Sep 2013 18:01:41 +0200 Subject: [PATCH 059/137] virtio_net: allocate queues, read macaddress, handle ioctl. --- .../drivers/network/virtio/virtio_net.cpp | 109 +++++++++++++++++- 1 file changed, 106 insertions(+), 3 deletions(-) diff --git a/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp b/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp index 1c9fe19866..4a6a66e3a5 100644 --- a/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp +++ b/src/add-ons/kernel/drivers/network/virtio/virtio_net.cpp @@ -7,10 +7,14 @@ #include #include +#include +#include + +#include "ether_driver.h" #define ETHER_ADDR_LEN ETHER_ADDRESS_LENGTH #include "virtio_net.h" - +#define MAX_FRAME_SIZE 1536 #define VIRTIO_NET_DRIVER_MODULE_NAME "drivers/network/virtio_net/driver_v1" #define VIRTIO_NET_DEVICE_MODULE_NAME "drivers/network/virtio_net/device_v1" @@ -24,6 +28,15 @@ typedef struct { uint32 features; + uint32 pairs_count; + ::virtio_queue* receive_queues; + ::virtio_queue* send_queues; + + + bool nonblocking; + uint32 maxframesize; + uint8 macaddr[6]; + } virtio_net_driver_info; @@ -120,8 +133,41 @@ virtio_net_init_device(void* _info, void** _cookie) info->virtio->negociate_features(info->virtio_device, 0 /* */, &info->features, &get_feature_name); + if ((info->features & VIRTIO_NET_F_MQ) != 0 + && info->virtio->read_device_config(info->virtio_device, + offsetof(struct virtio_net_config, max_virtqueue_pairs), + &info->pairs_count, sizeof(info->pairs_count)) == B_OK) { + system_info sysinfo; + if (get_system_info(&sysinfo) == B_OK + && info->pairs_count > sysinfo.cpu_count) { + info->pairs_count = sysinfo.cpu_count; + } + } else + info->pairs_count = 1; + // TODO read config - // TODO alloc queues and setup interrupts + + uint32 queueCount = info->pairs_count * 2; + if ((info->features & VIRTIO_NET_F_CTRL_VQ) != 0) + queueCount++; + ::virtio_queue virtioQueues[queueCount]; + status_t status = info->virtio->alloc_queues(info->virtio_device, queueCount, + virtioQueues); + if (status != B_OK) { + ERROR("queue allocation failed (%s)\n", strerror(status)); + return status; + } + + info->receive_queues = new(std::nothrow) virtio_queue[info->pairs_count]; + info->send_queues = new(std::nothrow) virtio_queue[info->pairs_count]; + if (info->receive_queues == NULL || info->receive_queues == NULL) + return B_NO_MEMORY; + for (uint32 i = 0; i < info->pairs_count; i++) { + info->receive_queues[i] = virtioQueues[i * 2]; + info->send_queues[i] = virtioQueues[i * 2 + 1]; + } + + // TODO setup interrupts *_cookie = info; return B_OK; @@ -147,8 +193,16 @@ virtio_net_open(void* _info, const char* path, int openMode, void** _cookie) if (handle == NULL) return B_NO_MEMORY; + info->nonblocking = (openMode & O_NONBLOCK) != 0; + info->maxframesize = MAX_FRAME_SIZE; handle->info = info; + if ((info->features & VIRTIO_NET_F_MAC) != 0) { + info->virtio->read_device_config(info->virtio_device, + offsetof(struct virtio_net_config, mac), + &info->macaddr, sizeof(info->macaddr)); + } + *_cookie = handle; return B_OK; } @@ -203,11 +257,60 @@ virtio_net_ioctl(void* cookie, uint32 op, void* buffer, size_t length) virtio_net_handle* handle = (virtio_net_handle*)cookie; virtio_net_driver_info* info = handle->info; - TRACE("ioctl(op = %ld)\n", op); + TRACE("ioctl(op = %lx)\n", op); switch (op) { + case ETHER_GETADDR: + TRACE("ioctl: get macaddr\n"); + memcpy(buffer, &info->macaddr, sizeof(info->macaddr)); + return B_OK; + + case ETHER_INIT: + TRACE("ioctl: init\n"); + return B_OK; + + case ETHER_GETFRAMESIZE: + TRACE("ioctl: get frame size\n"); + *(uint32*)buffer = info->maxframesize; + return B_OK; + + case ETHER_SETPROMISC: + TRACE("ioctl: set promisc\n"); + break; + + case ETHER_NONBLOCK: + info->nonblocking = *(int32 *)buffer == 0; + TRACE("ioctl: non blocking ? %s\n", info->nonblocking ? "yes" : "no"); + return B_OK; + + case ETHER_ADDMULTI: + TRACE("ioctl: add multicast\n"); + break; + + case ETHER_GET_LINK_STATE: + { + TRACE("ioctl: get link state\n"); + ether_link_state_t state; + uint16 status = VIRTIO_NET_S_LINK_UP; + if ((info->features & VIRTIO_NET_F_STATUS) != 0) { + info->virtio->read_device_config(info->virtio_device, + offsetof(struct virtio_net_config, status), + &status, sizeof(status)); + } + state.media = ((status & VIRTIO_NET_S_LINK_UP) != 0 ? IFM_ACTIVE : 0) + | IFM_ETHER | IFM_FULL_DUPLEX | IFM_10G_T; + state.speed = 10000000000ULL; + state.quality = 1000; + + return user_memcpy(buffer, &state, sizeof(ether_link_state_t)); + } + + default: + ERROR("ioctl: unknown message %" B_PRIx32 "\n", op); + break; } + return B_DEV_INVALID_IOCTL; } From b31f2d53e09d6d2914328227c18034cb6ad42bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sat, 14 Sep 2013 18:11:43 +0200 Subject: [PATCH 060/137] add a constant for 10G base T ethernet. --- headers/posix/net/if_media.h | 1 + src/bin/network/ifconfig/ifconfig.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/headers/posix/net/if_media.h b/headers/posix/net/if_media.h index e0fdc4e76d..ca67cf629d 100644 --- a/headers/posix/net/if_media.h +++ b/headers/posix/net/if_media.h @@ -31,6 +31,7 @@ #define IFM_100_TX 6 /* 100Base-TX - RJ45 */ #define IFM_1000_T 16 /* 1000Base-T - RJ45 */ #define IFM_1000_SX 18 /* 1000Base-SX - Fiber Optic */ +#define IFM_10G_T 22 /* 10GBase-T - RJ45 */ /* General options */ diff --git a/src/bin/network/ifconfig/ifconfig.cpp b/src/bin/network/ifconfig/ifconfig.cpp index e1030558ce..bd36e3c248 100644 --- a/src/bin/network/ifconfig/ifconfig.cpp +++ b/src/bin/network/ifconfig/ifconfig.cpp @@ -105,6 +105,7 @@ static const media_type kMediaTypes[] = { { IFM_100_TX, "100baseTX", "100 MBit, 100BASE-TX" }, { IFM_1000_T, "1000baseT", "1 GBit, 1000BASE-T" }, { IFM_1000_SX, "1000baseSX", "1 GBit, 1000BASE-SX" }, + { IFM_10G_T, "10GbaseT", "10 GBit, 10GBASE-T" }, { -1, NULL, NULL } }, { @@ -1012,4 +1013,3 @@ main(int argc, char** argv) list_interfaces(name); return 0; } - From cfa8ecbc8679200044b2922a753490e99972e88f Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Sat, 14 Sep 2013 20:13:36 +0200 Subject: [PATCH 061/137] ARM: boot: Make dd on MacOS happy Turns out dd on MacOS does not like '1M' as size descriptor, but wants '1m'. To prevent us breaking Linux builds (as it does not accept 1m), just use the actual number of bytes explicitely instead. --- src/system/boot/platform/u-boot/Jamfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/boot/platform/u-boot/Jamfile b/src/system/boot/platform/u-boot/Jamfile index f8fe507819..7ce4ed8623 100644 --- a/src/system/boot/platform/u-boot/Jamfile +++ b/src/system/boot/platform/u-boot/Jamfile @@ -151,7 +151,7 @@ actions BuildUImageScript1 rule BuildUBootSDImage image : files { Depends $(image) : $(files) ; - SDIMAGE_BLOCK_SIZE on $(image) = 1M ; + SDIMAGE_BLOCK_SIZE on $(image) = 1048576 ; # 1M SDIMAGE_SIZE on $(image) = $(HAIKU_BOARD_SDIMAGE_SIZE) ; SDIMAGE_FDISK on $(image) = $(HOST_SFDISK) ; SDIMAGE_FDISK_SCRIPT on $(image) = From eeb345aa17b6da6f92b5213949ad5064e410b757 Mon Sep 17 00:00:00 2001 From: John Scipione Date: Sat, 14 Sep 2013 14:55:53 -0400 Subject: [PATCH 062/137] Use uname -s instead of uname -o ...since BSD uname (on OS X at least) doesn't have a -o param, only a -s, Haiku has both, and both print "Haiku". --- build/scripts/build_cross_tools | 2 +- build/scripts/build_cross_tools_gcc4 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/scripts/build_cross_tools b/build/scripts/build_cross_tools index 9e2fd4edb0..37b7616b85 100755 --- a/build/scripts/build_cross_tools +++ b/build/scripts/build_cross_tools @@ -20,7 +20,7 @@ additionalMakeArgs=$* # additional flags for the binutils build. Should there ever be any other # flags than -jN, we need to handle this differently. -if [ `uname -o` = 'Haiku' ]; then +if [ `uname -s` = 'Haiku' ]; then # force cross-build if building on Haiku: buildhostMachine=i586-pc-haiku_buildhost buildHostSpec="--build=$buildhostMachine --host=$buildhostMachine" diff --git a/build/scripts/build_cross_tools_gcc4 b/build/scripts/build_cross_tools_gcc4 index f9b6023532..2d587720c6 100755 --- a/build/scripts/build_cross_tools_gcc4 +++ b/build/scripts/build_cross_tools_gcc4 @@ -50,7 +50,7 @@ arm-*) ;; esac -if [ `uname -o` = 'Haiku' ]; then +if [ `uname -s` = 'Haiku' ]; then # force cross-build if building on Haiku: buildhostMachine=${haikuMachine}_buildhost buildHostSpec="--build=$buildhostMachine --host=$buildhostMachine" From d05bb5a8e6dcd39282e42db9dce73bae587d68ae Mon Sep 17 00:00:00 2001 From: Jorma Karvonen Date: Sat, 14 Sep 2013 22:43:44 +0200 Subject: [PATCH 063/137] Localize bitsinfo Closes ticket #7162. Signed-off-by: Niels Sascha Reedijk --- src/tools/translation/bitsinfo/Jamfile | 13 ++++- src/tools/translation/bitsinfo/bitsinfo.cpp | 56 ++++++++++++-------- src/tools/translation/bitsinfo/bitsinfo.rdef | 17 ++++++ 3 files changed, 62 insertions(+), 24 deletions(-) create mode 100644 src/tools/translation/bitsinfo/bitsinfo.rdef diff --git a/src/tools/translation/bitsinfo/Jamfile b/src/tools/translation/bitsinfo/Jamfile index 50b011f5a5..f0215619ee 100644 --- a/src/tools/translation/bitsinfo/Jamfile +++ b/src/tools/translation/bitsinfo/Jamfile @@ -1,4 +1,15 @@ SubDir HAIKU_TOP src tools translation bitsinfo ; -BinCommand bitsinfo : bitsinfo.cpp : be $(TARGET_LIBSUPC++) ; +SetSubDirSupportedPlatformsBeOSCompatible ; +BinCommand bitsinfo : + bitsinfo.cpp + : be libbe.so $(HAIKU_LOCALE_LIBS) translation $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) ; + +AddResources bitsinfo : bitsinfo.rdef ; + +DoCatalogs bitsinfo : + x-vnd.Haiku-bitsinfo + : + bitsinfo.cpp +; diff --git a/src/tools/translation/bitsinfo/bitsinfo.cpp b/src/tools/translation/bitsinfo/bitsinfo.cpp index 7446228b86..81a1328ca4 100644 --- a/src/tools/translation/bitsinfo/bitsinfo.cpp +++ b/src/tools/translation/bitsinfo/bitsinfo.cpp @@ -38,10 +38,14 @@ #include #include #include +#include #include #include #include +#undef B_TRANSLATE_CONTEXT +#define B_TRANSLATE_CONTEXT "bitsinfo" + struct ColorSpaceName { color_space id; const char *name; @@ -62,7 +66,8 @@ PrintBitsInfo(const char *filepath, bool bdumppixels) // read in the rest of the header ssize_t size = sizeof(TranslatorBitmap); if (file.Read(reinterpret_cast (&header), size) != size) { - printf("\nError: Unable to read the Be bitmap header.\n"); + printf(B_TRANSLATE("\nError: Unable to read the Be bitmap " + "header.\n")); return; } if (!bdumppixels) @@ -72,28 +77,29 @@ PrintBitsInfo(const char *filepath, bool bdumppixels) // convert to host byte order if (swap_data(B_UINT32_TYPE, &header, sizeof(TranslatorBitmap), B_SWAP_BENDIAN_TO_HOST) != B_OK) { - printf("\nError: Unable to swap byte order\n"); + printf(B_TRANSLATE("\nError: Unable to swap byte order\n")); return; } - printf("\nBe bitmap (\"bits\") header for: %s\n\n", filepath); + printf(B_TRANSLATE("\nBe bitmap (\"bits\") header for: %s\n\n"), + filepath); const uint32 kbitsmagic = 0x62697473UL; // in ASCII, this number looks like "bits" - printf("magic number: 0x%.8lx ", header.magic); if (header.magic == kbitsmagic) - printf("(valid)\n"); + printf(B_TRANSLATE("magic number: 0x%.8lx (valid)\n"), + header.magic); else - printf("(INVALID, should be: 0x%.8lx)\n", - kbitsmagic); - printf("bounds: (%f, %f, %f, %f)\n", + printf(B_TRANSLATE("magic number: 0x%.8lx (INVALID, should be: " + "0x%.8lx)\n"), header.magic, kbitsmagic); + printf(B_TRANSLATE("bounds: (%f, %f, %f, %f)\n"), header.bounds.left, header.bounds.top, header.bounds.right, header.bounds.bottom); - printf("dimensions: %d x %d\n", + printf(B_TRANSLATE("dimensions: %d x %d\n"), static_cast(header.bounds.Width() + 1), static_cast(header.bounds.Height() + 1)); - printf("bytes per row: %u\n", + printf(B_TRANSLATE("bytes per row: %u\n"), static_cast(header.rowBytes)); // print out colorspace if it matches an item in the list @@ -149,15 +155,15 @@ PrintBitsInfo(const char *filepath, bool bdumppixels) int32 i; for (i = 0; i < kncolorspaces; i++) { if (header.colors == colorspaces[i].id) { - printf("color space: %s\n", colorspaces[i].name); + printf(B_TRANSLATE("color space: %s\n"), colorspaces[i].name); break; } } if (i == kncolorspaces) - printf("color space: Unknown (0x%.8lx)\n", + printf(B_TRANSLATE("color space: Unknown (0x%.8lx)\n"), static_cast(header.colors)); - printf("data size: %u\n", + printf(B_TRANSLATE("data size: %u\n"), static_cast(header.dataSize)); if (bdumppixels) { @@ -178,18 +184,19 @@ PrintBitsInfo(const char *filepath, bool bdumppixels) break; default: - printf("Sorry, %s isn't supported yet" - " for this color space\n", kpixels); + printf(B_TRANSLATE("Sorry, %s isn't supported yet" + " for this color space\n"), kpixels); return; } uint8 *prow = new uint8[header.rowBytes]; if (!prow) { - printf("Error: Not enough memory for row buffer\n"); + printf(B_TRANSLATE("Error: Not enough memory for row " + "buffer\n")); return; } ssize_t ret, n; uint32 totalbytes = 0; - printf("pixel data (%s):\n", components); + printf(B_TRANSLATE("pixel data (%s):\n"), components); while ((ret = file.Read(prow, header.rowBytes)) > 0) { n = 0; while (n < ret) { @@ -205,18 +212,21 @@ PrintBitsInfo(const char *filepath, bool bdumppixels) } } else - printf("Error opening %s\n", filepath); + printf(B_TRANSLATE_COMMENT("Error opening %s\n", + "file path is opening"), filepath); } int main(int argc, char **argv) { if (argc == 1) { - printf("\nbitsinfo - reports information about a Be bitmap (\"bits\") image\n"); - printf("\nUsage:\n"); - printf("bitsinfo [options] filename.bits\n\n"); - printf("Options:\n\n"); - printf("\t%s \t print RGB color for each pixel\n", kpixels); + printf(B_TRANSLATE("\nbitsinfo - reports information about a Be " + "bitmap (\"bits\") image\n")); + printf(B_TRANSLATE("\nUsage:\n")); + printf(B_TRANSLATE("bitsinfo [options] filename.bits\n\n")); + printf(B_TRANSLATE("Options:\n\n")); + printf(B_TRANSLATE("\t%s \t print RGB color for each pixel\n"), + kpixels); } else { int32 first = 1; diff --git a/src/tools/translation/bitsinfo/bitsinfo.rdef b/src/tools/translation/bitsinfo/bitsinfo.rdef new file mode 100644 index 0000000000..935e1e038a --- /dev/null +++ b/src/tools/translation/bitsinfo/bitsinfo.rdef @@ -0,0 +1,17 @@ +/* + * bitsinfo.rdef + */ + +resource app_signature "application/x-vnd.Haiku-bitsinfo"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "bitsinfo displays text information about Be bitmap format ("bits") images.", + long_info = "Haiku bitsinfo is a command line tool for displaying text information about Be bitmap format ("bits") images. Written by Michael Wilber, OBOS Translation Kit Team, Copyright © 2003 OpenBeOS Project." +}; + +resource app_flags B_SINGLE_LAUNCH; From ba4746794a3f91350d98084f5ebfe3e7d517a2fd Mon Sep 17 00:00:00 2001 From: Jorma Karvonen Date: Sat, 14 Sep 2013 22:47:58 +0200 Subject: [PATCH 064/137] Localize bmpinfo Closes ticket #7164 Signed-off-by: Niels Sascha Reedijk --- src/tools/translation/bmpinfo/Jamfile | 9 +- src/tools/translation/bmpinfo/bmpinfo.cpp | 99 +++++++++++++--------- src/tools/translation/bmpinfo/bmpinfo.rdef | 17 ++++ 3 files changed, 85 insertions(+), 40 deletions(-) create mode 100644 src/tools/translation/bmpinfo/bmpinfo.rdef diff --git a/src/tools/translation/bmpinfo/Jamfile b/src/tools/translation/bmpinfo/Jamfile index 584b9a15cf..fae0e01048 100644 --- a/src/tools/translation/bmpinfo/Jamfile +++ b/src/tools/translation/bmpinfo/Jamfile @@ -1,4 +1,11 @@ SubDir HAIKU_TOP src tools translation bmpinfo ; -BinCommand bmpinfo : bmpinfo.cpp : be ; +BinCommand bmpinfo : bmpinfo.cpp : be libbe.so $(HAIKU_LOCALE_LIBS) translation $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) ; +AddResources bmpinfo : bmpinfo.rdef ; + +DoCatalogs bmpinfo : + x-vnd.Haiku-bmpsinfo + : + bmpinfo.cpp +; diff --git a/src/tools/translation/bmpinfo/bmpinfo.cpp b/src/tools/translation/bmpinfo/bmpinfo.cpp index b5eb0d7038..c5e7a516c0 100644 --- a/src/tools/translation/bmpinfo/bmpinfo.cpp +++ b/src/tools/translation/bmpinfo/bmpinfo.cpp @@ -36,10 +36,14 @@ #include #include #include +#include #include #include #include +#undef B_TRANSLATE_CONTEXT +#define B_TRANSLATE_CONTEXT "bmpinfo" + #define BMP_NO_COMPRESS 0 #define BMP_RLE8_COMPRESS 1 #define BMP_RLE4_COMPRESS 2 @@ -82,7 +86,7 @@ print_bmp_info(BFile &file) ssize_t size = 14; if (file.Read(buf, size) != size) { - printf("Error: unable to read BMP file header\n"); + printf(B_TRANSLATE("Error: unable to read BMP file header\n")); return; } @@ -96,16 +100,18 @@ print_bmp_info(BFile &file) swap_data(B_UINT32_TYPE, (reinterpret_cast (&fh)) + 2, 12, B_SWAP_LENDIAN_TO_HOST); - printf("\nFile Header:\n"); - printf(" magic: 0x%.4x (should be: 0x424d)\n", fh.magic); - printf(" file size: 0x%.8lx (%lu)\n", fh.fileSize, fh.fileSize); - printf(" reserved: 0x%.8lx (should be: 0x%.8x)\n", fh.reserved, 0); - printf("data offset: 0x%.8lx (%lu) (should be: >= 54 for MS format " - "and >= 26 for OS/2 format)\n", fh.dataOffset, fh.dataOffset); + printf(B_TRANSLATE("\nFile Header:\n")); + printf(B_TRANSLATE(" magic: 0x%.4x (should be: 0x424d)\n"), fh.magic); + printf(B_TRANSLATE(" file size: 0x%.8lx (%lu)\n"), fh.fileSize, + fh.fileSize); + printf(B_TRANSLATE(" reserved: 0x%.8lx (should be: 0x%.8x)\n"), + fh.reserved, 0); + printf(B_TRANSLATE("data offset: 0x%.8lx (%lu) (should be: >= 54 for MS " + "format and >= 26 for OS/2 format)\n"), fh.dataOffset, fh.dataOffset); uint32 headersize = 0; if (file.Read(&headersize, 4) != 4) { - printf("Error: unable to read info header size\n"); + printf(B_TRANSLATE("Error: unable to read info header size\n")); return; } swap_data(B_UINT32_TYPE, &headersize, 4, B_SWAP_LENDIAN_TO_HOST); @@ -115,7 +121,7 @@ print_bmp_info(BFile &file) MSInfoHeader msh; msh.size = headersize; if (file.Read(reinterpret_cast (&msh) + 4, 36) != 36) { - printf("Error: unable to read entire MS info header\n"); + printf(B_TRANSLATE("Error: unable to read entire MS info header\n")); return; } @@ -123,22 +129,33 @@ print_bmp_info(BFile &file) swap_data(B_UINT32_TYPE, reinterpret_cast (&msh) + 4, 36, B_SWAP_LENDIAN_TO_HOST); - printf("\nMS Info Header:\n"); - printf(" header size: 0x%.8lx (%lu) (should be: 40)\n", msh.size, msh.size); - printf(" width: %lu\n", msh.width); - printf(" height: %lu\n", msh.height); - printf(" planes: %u (should be: 1)\n", msh.planes); - printf(" bits per pixel: %u (should be: 1,4,8,16,24 or 32)\n", msh.bitsperpixel); - printf(" compression: %s (%lu)\n", - ((msh.compression == BMP_NO_COMPRESS) ? ("none") : - ((msh.compression == BMP_RLE8_COMPRESS) ? ("RLE 8") : - ((msh.compression == BMP_RLE4_COMPRESS) ? ("RLE 4") : - ("unknown")))), msh.compression); - printf(" image size: 0x%.8lx (%lu)\n", msh.imagesize, msh.imagesize); - printf(" x pixels/meter: %lu\n", msh.xpixperm); - printf(" y pixels/meter: %lu\n", msh.ypixperm); - printf(" colors used: %lu\n", msh.colorsused); - printf("colors important: %lu\n", msh.colorsimportant); + printf(B_TRANSLATE("\nMS Info Header:\n")); + printf(B_TRANSLATE(" header size: 0x%.8lx (%lu) (should be: " + "40)\n"), msh.size, msh.size); + printf(B_TRANSLATE(" width: %lu\n"), msh.width); + printf(B_TRANSLATE(" height: %lu\n"), msh.height); + printf(B_TRANSLATE(" planes: %u (should be: 1)\n"), + msh.planes); + printf(B_TRANSLATE(" bits per pixel: %u (should be: 1,4,8,16,24 or " + "32)\n"), msh.bitsperpixel); + if (msh.compression == BMP_NO_COMPRESS) + printf(B_TRANSLATE(" compression: none (%lu)\n"), + msh.compression); + else if (msh.compression == BMP_RLE8_COMPRESS) + printf(B_TRANSLATE(" compression: RLE8 (%lu)\n"), + msh.compression); + else if (msh.compression == BMP_RLE4_COMPRESS) + printf(B_TRANSLATE(" compression: RLE4 (%lu)\n"), + msh.compression); + else + printf(B_TRANSLATE(" compression: unknown (%lu)\n"), + msh.compression); + printf(B_TRANSLATE(" image size: 0x%.8lx (%lu)\n"), msh.imagesize, + msh.imagesize); + printf(B_TRANSLATE(" x pixels/meter: %lu\n"), msh.xpixperm); + printf(B_TRANSLATE(" y pixels/meter: %lu\n"), msh.ypixperm); + printf(B_TRANSLATE(" colors used: %lu\n"), msh.colorsused); + printf(B_TRANSLATE("colors important: %lu\n"), msh.colorsimportant); } else if (headersize == sizeof(OS2InfoHeader)) { // OS/2 format @@ -146,7 +163,8 @@ print_bmp_info(BFile &file) OS2InfoHeader os2; os2.size = headersize; if (file.Read(reinterpret_cast (&os2) + 4, 8) != 8) { - printf("Error: unable to read entire OS/2 info header\n"); + printf(B_TRANSLATE("Error: unable to read entire OS/2 info " + "header\n")); return; } @@ -154,17 +172,18 @@ print_bmp_info(BFile &file) swap_data(B_UINT32_TYPE, reinterpret_cast (&os2) + 4, 8, B_SWAP_LENDIAN_TO_HOST); - printf("\nOS/2 Info Header:\n"); - printf(" header size: 0x%.8lx (%lu) (should be: 12)\n", os2.size, os2.size); - printf(" width: %u\n", os2.width); - printf(" height: %u\n", os2.height); - printf(" planes: %u (should be: 1)\n", os2.planes); - printf("bits per pixel: %u (should be: 1,4,8 or 24)\n", + printf(B_TRANSLATE("\nOS/2 Info Header:\n")); + printf(B_TRANSLATE(" header size: 0x%.8lx (%lu) (should be: 12)\n"), + os2.size, os2.size); + printf(B_TRANSLATE(" width: %u\n"), os2.width); + printf(B_TRANSLATE(" height: %u\n"), os2.height); + printf(B_TRANSLATE(" planes: %u (should be: 1)\n"), os2.planes); + printf(B_TRANSLATE("bits per pixel: %u (should be: 1,4,8 or 24)\n"), os2.bitsperpixel); } else - printf("Error: info header size (%lu) does not match MS or OS/2 " - "info header size\n", headersize); + printf(B_TRANSLATE("Error: info header size (%lu) does not match MS " + "or OS/2 info header size\n"), headersize); } int @@ -173,18 +192,20 @@ main(int argc, char **argv) printf("\n"); if (argc == 1) { - printf("bmpinfo - reports information about a BMP image file\n"); - printf("\nUsage:\n"); - printf("bmpinfo filename.bmp\n"); + printf(B_TRANSLATE("bmpinfo - reports information about a BMP image " + "file\n")); + printf(B_TRANSLATE("\nUsage:\n")); + printf(B_TRANSLATE("bmpinfo filename.bmp\n")); } else { BFile file; for (int32 i = 1; i < argc; i++) { if (file.SetTo(argv[i], B_READ_ONLY) != B_OK) - printf("\nError opening %s\n", argv[i]); + printf(B_TRANSLATE("\nError opening %s\n"), argv[i]); else { - printf("\nBMP image information for: %s\n", argv[i]); + printf(B_TRANSLATE("\nBMP image information for: %s\n"), + argv[i]); print_bmp_info(file); } } diff --git a/src/tools/translation/bmpinfo/bmpinfo.rdef b/src/tools/translation/bmpinfo/bmpinfo.rdef new file mode 100644 index 0000000000..90e61483c4 --- /dev/null +++ b/src/tools/translation/bmpinfo/bmpinfo.rdef @@ -0,0 +1,17 @@ +/* + * bmpinfo.rdef + */ + +resource app_signature "application/x-vnd.Haiku-bmpinfo"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "bmpinfo displays text information about BMP images.", + long_info = "Haiku bmpinfo is a command line tool for displaying text information about BMP images. Written by Michael Wilber, OBOS Translation Kit Team, Copyright © 2003 OpenBeOS Project." +}; + +resource app_flags B_SINGLE_LAUNCH; From 9d79ce816bf1f11f1217ad93c0f126b39d46457a Mon Sep 17 00:00:00 2001 From: Jorma Karvonen Date: Sat, 14 Sep 2013 22:52:43 +0200 Subject: [PATCH 065/137] Localize tgainfo Closes ticket #7168 Signed-off-by: Niels Sascha Reedijk --- src/tools/translation/bitsinfo/Jamfile | 2 - src/tools/translation/tgainfo/Jamfile | 11 +- src/tools/translation/tgainfo/tgainfo.cpp | 215 +++++++++++++-------- src/tools/translation/tgainfo/tgainfo.rdef | 17 ++ 4 files changed, 164 insertions(+), 81 deletions(-) create mode 100644 src/tools/translation/tgainfo/tgainfo.rdef diff --git a/src/tools/translation/bitsinfo/Jamfile b/src/tools/translation/bitsinfo/Jamfile index f0215619ee..eca781ef8a 100644 --- a/src/tools/translation/bitsinfo/Jamfile +++ b/src/tools/translation/bitsinfo/Jamfile @@ -1,7 +1,5 @@ SubDir HAIKU_TOP src tools translation bitsinfo ; -SetSubDirSupportedPlatformsBeOSCompatible ; - BinCommand bitsinfo : bitsinfo.cpp : be libbe.so $(HAIKU_LOCALE_LIBS) translation $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) ; diff --git a/src/tools/translation/tgainfo/Jamfile b/src/tools/translation/tgainfo/Jamfile index 39e8a88dc1..b4b5eb4ddc 100644 --- a/src/tools/translation/tgainfo/Jamfile +++ b/src/tools/translation/tgainfo/Jamfile @@ -1,4 +1,13 @@ SubDir HAIKU_TOP src tools translation tgainfo ; -BinCommand tgainfo : tgainfo.cpp : be ; +BinCommand tgainfo : + tgainfo.cpp + : be libbe.so $(HAIKU_LOCALE_LIBS) translation $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) ; +AddResources tgainfo : tgainfo.rdef ; + +DoCatalogs tgainfo : + x-vnd.Haiku-tgainfo + : + tgainfo.cpp +; diff --git a/src/tools/translation/tgainfo/tgainfo.cpp b/src/tools/translation/tgainfo/tgainfo.cpp index e3036f5fc2..925c35e97e 100644 --- a/src/tools/translation/tgainfo/tgainfo.cpp +++ b/src/tools/translation/tgainfo/tgainfo.cpp @@ -36,10 +36,14 @@ #include #include #include +#include #include #include #include +#undef B_TRANSLATE_CONTEXT +#define B_TRANSLATE_CONTEXT "tgainfo" + #define max(x,y) ((x > y) ? x : y) #define DATA_BUFFER_SIZE 64 @@ -99,8 +103,8 @@ const char * colormaptype(uint8 n) { switch (n) { - case 0: return "No colormap"; - case 1: return "colormap"; + case 0: return B_TRANSLATE("No colormap"); + case 1: return B_TRANSLATE("colormap"); } return "unknown"; } @@ -109,15 +113,16 @@ const char * imagetype(uint8 n) { switch (n) { - case 0: return "No Image Data"; - case 1: return "colormap"; - case 2: return "true color"; - case 3: return "grayscale"; - case 9: return "RLE colormap"; - case 10: return "RLE true color"; - case 11: return "RLE grayscale"; + case 0: return B_TRANSLATE("No Image Data"); + case 1: return B_TRANSLATE("colormap"); + case 2: return B_TRANSLATE("true color"); + case 3: return B_TRANSLATE("grayscale"); + case 9: return B_TRANSLATE("RLE colormap"); + case 10: return B_TRANSLATE("RLE true color"); + case 11: return B_TRANSLATE("RLE grayscale"); + default: break; } - return "unknown"; + return B_TRANSLATE("unknown"); } uint16 @@ -140,7 +145,7 @@ print_tga_info(BFile &file) // read in TGA headers ssize_t size = TGA_HEADERS_SIZE; if (size > 0 && file.Read(buf, size) != size) { - printf("Error: unable to read all TGA headers\n"); + printf(B_TRANSLATE("Error: unable to read all TGA headers\n")); return; } @@ -150,12 +155,15 @@ print_tga_info(BFile &file) fh.colormaptype = buf[1]; fh.imagetype = buf[2]; - printf("\nFile Header:\n"); - printf(" id length: %d\n", fh.idlength); + printf(B_TRANSLATE("\nFile Header:\n")); + printf(B_TRANSLATE(" id length: %d\n"), static_cast(fh.idlength)); - printf("colormap type: %d (%s)\n", fh.colormaptype, - colormaptype(fh.colormaptype)); - printf(" image type: %d (%s)\n", fh.imagetype, imagetype(fh.imagetype)); + printf(B_TRANSLATE("colormap type: %d (%s)\n"), + static_cast(fh.colormaptype), + static_cast(colormaptype(fh.colormaptype))); + printf(B_TRANSLATE(" image type: %d (%s)\n"), + static_cast(fh.imagetype), + static_cast(imagetype(fh.imagetype))); // TGA color map spec @@ -164,10 +172,13 @@ print_tga_info(BFile &file) mapspec.length = tga_uint16(reinterpret_cast(buf), 5); mapspec.entrysize = buf[7]; - printf("\nColormap Spec:\n"); - printf("first entry: %d\n", mapspec.firstentry); - printf(" length: %d\n", mapspec.length); - printf(" entry size: %d\n", mapspec.entrysize); + printf(B_TRANSLATE("\nColormap Spec:\n")); + printf(B_TRANSLATE("first entry: %d\n"), + static_cast(mapspec.firstentry)); + printf(B_TRANSLATE(" length: %d\n"), + static_cast(mapspec.length)); + printf(B_TRANSLATE(" entry size: %d\n"), + static_cast(mapspec.entrysize)); // TGA image spec @@ -179,20 +190,47 @@ print_tga_info(BFile &file) imagespec.depth = buf[16]; imagespec.descriptor = buf[17]; - printf("\nImage Spec:\n"); - printf(" x origin: %d\n", imagespec.xorigin); - printf(" y origin: %d\n", imagespec.yorigin); - printf(" width: %d\n", imagespec.width); - printf(" height: %d\n", imagespec.height); - printf(" depth: %d\n", imagespec.depth); - printf("descriptor: 0x%.2x\n", imagespec.descriptor); - printf("\talpha (attr): %d\n", - imagespec.descriptor & TGA_DESC_ALPHABITS); - printf("\t origin: %d (%s %s)\n", - imagespec.descriptor & (TGA_ORIGIN_VERT_BIT | TGA_ORIGIN_HORZ_BIT), - ((imagespec.descriptor & TGA_ORIGIN_VERT_BIT) ? "top" : "bottom"), - ((imagespec.descriptor & TGA_ORIGIN_HORZ_BIT) ? "right" : "left")); - printf("\t bits 7 & 6: %d\n", imagespec.descriptor & TGA_DESC_BITS76); + printf(B_TRANSLATE("\nImage Spec:\n")); + printf(B_TRANSLATE(" x origin: %d\n"), + static_cast(imagespec.xorigin)); + printf(B_TRANSLATE(" y origin: %d\n"), + static_cast(imagespec.yorigin)); + printf(B_TRANSLATE(" width: %d\n"), + static_cast(imagespec.width)); + printf(B_TRANSLATE(" height: %d\n"), + static_cast(imagespec.height)); + printf(B_TRANSLATE(" depth: %d\n"), + static_cast(imagespec.depth)); + printf(B_TRANSLATE("descriptor: 0x%.2x\n"), + static_cast(imagespec.descriptor)); + printf(B_TRANSLATE("\talpha (attr): %d\n"), + static_cast(imagespec.descriptor & TGA_DESC_ALPHABITS)); + if (imagespec.descriptor & TGA_ORIGIN_VERT_BIT) + if (imagespec.descriptor & TGA_ORIGIN_HORZ_BIT) + printf(B_TRANSLATE("\t origin: %d (%s %s)\n"), + static_cast(imagespec.descriptor & (TGA_ORIGIN_VERT_BIT + | TGA_ORIGIN_HORZ_BIT)), static_cast("top"), + static_cast("right")); + else + printf(B_TRANSLATE("\t origin: %d (%s %s)\n"), + static_cast(imagespec.descriptor & (TGA_ORIGIN_VERT_BIT + | TGA_ORIGIN_HORZ_BIT)), static_cast("top"), + static_cast("left")); + else + if (imagespec.descriptor & TGA_ORIGIN_HORZ_BIT) + printf(B_TRANSLATE("\t origin: %d (%s %s)\n"), + static_cast(imagespec.descriptor & (TGA_ORIGIN_VERT_BIT + | TGA_ORIGIN_HORZ_BIT)), static_cast("bottom"), + static_cast("right")); + else + printf(B_TRANSLATE("\t origin: %d (%s %s)\n"), + static_cast(imagespec.descriptor & (TGA_ORIGIN_VERT_BIT + | TGA_ORIGIN_HORZ_BIT)), static_cast("bottom"), + static_cast("left")); + + + printf(B_TRANSLATE("\t bits 7 & 6: %d\n"), + static_cast(imagespec.descriptor & TGA_DESC_BITS76)); // Optional TGA Footer @@ -208,107 +246,128 @@ print_tga_info(BFile &file) extoffset = tga_uint32(tgafooter, 0); devoffset = tga_uint32(tgafooter, 4); - printf("\nTGA Footer:\n"); - printf("extension offset: 0x%.8lx (%ld)\n", extoffset, extoffset); - printf("developer offset: 0x%.8lx (%ld)\n", devoffset, devoffset); - printf("signature: %s\n", tgafooter + 8); + printf(B_TRANSLATE("\nTGA Footer:\n")); + printf(B_TRANSLATE("extension offset: 0x%.8lx (%ld)\n"), + static_cast(extoffset), + static_cast(extoffset)); + printf(B_TRANSLATE("developer offset: 0x%.8lx (%ld)\n"), + static_cast(devoffset), + static_cast(devoffset)); + printf(B_TRANSLATE("signature: %s\n"), tgafooter + 8); if (extoffset) { char extbuf[TGA_EXT_LEN]; if (file.ReadAt(extoffset, extbuf, TGA_EXT_LEN) == TGA_EXT_LEN) { - printf("\nExtension Area:\n"); + printf(B_TRANSLATE("\nExtension Area:\n")); char strbuffer[LINE_LEN]; uint16 extsize = tga_uint16(extbuf, 0); if (extsize < TGA_EXT_LEN) { - printf("\nError: extension area is too small (%d)\n", extsize); + printf(B_TRANSLATE("\nError: extension " + "area is too small (%d)\n"), extsize); return; } - printf("size: %d\n", extsize); + printf(B_TRANSLATE("size: %d\n"), extsize); memset(strbuffer, 0, LINE_LEN); strncpy(strbuffer, extbuf + 2, 41); printf("author: \"%s\"\n", strbuffer); - printf("comments:\n"); + printf(B_TRANSLATE("comments:\n")); for (int32 i = 0; i < 4; i++) { memset(strbuffer, 0, LINE_LEN); strcpy(strbuffer, extbuf + 43 + (i * 81)); - printf("\tline %ld: \"%s\"\n", i + 1, strbuffer); + printf(B_TRANSLATE("\tline %ld: \"%s\"\n"), + static_cast(i + 1), + static_cast(strbuffer)); } - printf("date/time (yyyy-mm-dd hh:mm:ss): %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n", + printf(B_TRANSLATE("date/time (yyyy-mm-dd hh:mm:ss): " + "%.4d-%.2d-%.2d %.2d:%.2d:%.2d\n"), tga_uint16(extbuf, 367), tga_uint16(extbuf, 369), tga_uint16(extbuf, 371), tga_uint16(extbuf, 373), tga_uint16(extbuf, 375), tga_uint16(extbuf, 377)); memset(strbuffer, 0, LINE_LEN); strncpy(strbuffer, extbuf + 379, 41); - printf("job name: \"%s\"\n", strbuffer); + printf(B_TRANSLATE("job name: \"%s\"\n"), strbuffer); - printf("job time (hh:mm:ss): %.2d:%.2d:%.2d\n", - tga_uint16(extbuf, 420), tga_uint16(extbuf, 422), - tga_uint16(extbuf, 424)); + printf(B_TRANSLATE("job time (hh:mm:ss): " + "%.2d:%.2d:%.2d\n"), tga_uint16(extbuf, 420), + tga_uint16(extbuf, 422), tga_uint16(extbuf, 424)); memset(strbuffer, 0, LINE_LEN); strncpy(strbuffer, extbuf + 426, 41); - printf("software id: \"%s\"\n", strbuffer); + printf(B_TRANSLATE("software id: \"%s\"\n"), + strbuffer); char strver[] = "[null]"; if (extbuf[469] != '\0') { strver[0] = extbuf[469]; strver[1] = '\0'; } - printf("software version, letter: %d, %s\n", - tga_uint16(extbuf, 467), strver); + printf(B_TRANSLATE("software version, letter: %d, " + "%s\n"), tga_uint16(extbuf, 467), strver); - printf("key color (A,R,G,B): %d, %d, %d, %d\n", - extbuf[470], extbuf[471], extbuf[472], extbuf[473]); + printf(B_TRANSLATE("key color (A,R,G,B): %d, %d, %d, " + "%d\n"), extbuf[470], extbuf[471], extbuf[472], + extbuf[473]); - printf("pixel aspect ratio: %d / %d\n", + printf(B_TRANSLATE("pixel aspect ratio: %d / %d\n"), tga_uint16(extbuf, 474), tga_uint16(extbuf, 476)); - printf("gamma value: %d / %d\n", + printf(B_TRANSLATE("gamma value: %d / %d\n"), tga_uint16(extbuf, 478), tga_uint16(extbuf, 480)); - printf("color correction offset: 0x%.8lx (%ld)\n", - tga_uint32(extbuf, 482), tga_uint32(extbuf, 482)); - printf("postage stamp offset: 0x%.8lx (%ld)\n", - tga_uint32(extbuf, 486), tga_uint32(extbuf, 486)); - printf("scan line offset: 0x%.8lx (%ld)\n", - tga_uint32(extbuf, 490), tga_uint32(extbuf, 490)); + printf(B_TRANSLATE("color correction offset: 0x%.8lx " + "(%ld)\n"), tga_uint32(extbuf, 482), + tga_uint32(extbuf, 482)); + printf(B_TRANSLATE("postage stamp offset: 0x%.8lx " + "(%ld)\n"), tga_uint32(extbuf, 486), + tga_uint32(extbuf, 486)); + printf(B_TRANSLATE("scan line offset: 0x%.8lx " + "(%ld)\n"), tga_uint32(extbuf, 490), + tga_uint32(extbuf, 490)); const char *strattrtype = NULL; uint8 attrtype = extbuf[494]; switch (attrtype) { - case 0: strattrtype = "no alpha"; break; - case 1: strattrtype = "undefined, ignore"; break; - case 2: strattrtype = "undefined, retain"; break; - case 3: strattrtype = "alpha"; break; - case 4: strattrtype = "pre-multiplied alpha"; break; + case 0: strattrtype + = B_TRANSLATE("no alpha"); break; + case 1: strattrtype + = B_TRANSLATE("undefined, ignore"); break; + case 2: strattrtype + = B_TRANSLATE("undefined, retain"); break; + case 3: strattrtype + = B_TRANSLATE("alpha"); break; + case 4: strattrtype + = B_TRANSLATE("pre-multiplied alpha"); break; default: if (attrtype > 4 && attrtype < 128) - strattrtype = "reserved"; + strattrtype = B_TRANSLATE("reserved"); else - strattrtype = "unassigned"; + strattrtype = B_TRANSLATE("unassigned"); break; } - printf("attributes type: %d (%s)\n", attrtype, strattrtype); + printf(B_TRANSLATE("attributes type: %d (%s)\n"), + attrtype, strattrtype); } else - printf("\nError: Unable to read entire extension area\n"); + printf(B_TRANSLATE("\nError: Unable to read entire " + "extension area\n")); } } else - printf("\nTGA footer not found\n"); + printf(B_TRANSLATE("\nTGA footer not found\n")); } else - printf("\nError: Unable to read TGA footer section\n"); + printf(B_TRANSLATE("\nError: Unable to read TGA footer " + "section\n")); } else - printf("\nError: Unable to get file size\n"); + printf(B_TRANSLATE("\nError: Unable to get file size\n")); } int @@ -317,18 +376,18 @@ main(int argc, char **argv) printf("\n"); if (argc == 1) { - printf("tgainfo - reports information about a TGA image file\n"); - printf("\nUsage:\n"); - printf("tgainfo filename.tga\n"); + printf(B_TRANSLATE("tgainfo - reports information about a TGA image file\n")); + printf(B_TRANSLATE("\nUsage:\n")); + printf(B_TRANSLATE("tgainfo filename.tga\n")); } else { BFile file; for (int32 i = 1; i < argc; i++) { if (file.SetTo(argv[i], B_READ_ONLY) != B_OK) - printf("\nError opening %s\n", argv[i]); + printf(B_TRANSLATE("\nError opening %s\n"), argv[i]); else { - printf("\nTGA image information for: %s\n", argv[i]); + printf(B_TRANSLATE("\nTGA image information for: %s\n"), argv[i]); print_tga_info(file); } } diff --git a/src/tools/translation/tgainfo/tgainfo.rdef b/src/tools/translation/tgainfo/tgainfo.rdef new file mode 100644 index 0000000000..3e0810f676 --- /dev/null +++ b/src/tools/translation/tgainfo/tgainfo.rdef @@ -0,0 +1,17 @@ +/* + * tgainfo.rdef + */ + +resource app_signature "application/x-vnd.Haiku-tgainfo"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "tgainfo displays text information about TGA images.", + long_info = "Haiku tgainfo is a command line tool for displaying text information about TGA images. Written by Michael Wilber, OBOS Translation Kit Team, Copyright © 2003 OpenBeOS Project." +}; + +resource app_flags B_SINGLE_LAUNCH; From 90742b59beae32ae47a3949339080a309f5a36f3 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Sat, 14 Sep 2013 20:28:54 +0200 Subject: [PATCH 066/137] ARM: boot: pass boot disk identifier This to stop the vfs_boot.cpp code from complaining. --- src/system/boot/platform/u-boot/devices.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/system/boot/platform/u-boot/devices.cpp b/src/system/boot/platform/u-boot/devices.cpp index 650211b6ee..ac380a77a3 100644 --- a/src/system/boot/platform/u-boot/devices.cpp +++ b/src/system/boot/platform/u-boot/devices.cpp @@ -5,10 +5,12 @@ #include -#include + +#include #include -#include +#include #include +#include #define TRACE_DEVICES #ifdef TRACE_DEVICES @@ -73,6 +75,18 @@ platform_add_block_devices(stage2_args *args, NodeList *devicesList) status_t platform_register_boot_device(Node *device) { - TRACE("platform_register_boot_device\n"); + disk_identifier disk_ident; + disk_ident.bus_type = UNKNOWN_BUS; + disk_ident.device_type = UNKNOWN_DEVICE; + disk_ident.device.unknown.size = device->Size(); + + for (int32 i = 0; i < NUM_DISK_CHECK_SUMS; i++) { + disk_ident.device.unknown.check_sums[i].offset = -1; + disk_ident.device.unknown.check_sums[i].sum = 0; + } + + gBootVolume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, + &disk_ident, sizeof(disk_ident)); + return B_OK; } From 20d9063c36be668dcf5519c7aa7baf249c2e79a7 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Sun, 15 Sep 2013 03:47:40 +0200 Subject: [PATCH 067/137] debugger/debuganalyzer: Remove the explicit -Werror from Jamfile Specifying -Werror in the Jamfiles directly prevents the build system from disabling error-on-warning for some arch specific warnings (or even globally), breaking the ARM build. The "src/apps" directory is already setup to compile with -Werror by the build system anyway, so remove the explicit setting here. --- src/apps/debuganalyzer/gui/Jamfile | 3 --- src/apps/debuganalyzer/gui/chart/Jamfile | 3 --- src/apps/debuganalyzer/gui/main_window/Jamfile | 3 --- src/apps/debuganalyzer/gui/table/Jamfile | 3 --- src/apps/debuganalyzer/gui/thread_window/Jamfile | 3 --- src/apps/debuganalyzer/model/Jamfile | 3 --- src/apps/debuganalyzer/model_loader/Jamfile | 3 --- src/apps/debuganalyzer/util/Jamfile | 3 --- src/apps/debugger/Jamfile | 3 --- src/apps/debugger/arch/x86/disasm/Jamfile | 3 --- src/apps/debugger/arch/x86_64/disasm/Jamfile | 3 --- src/apps/debugger/demangler/Jamfile | 3 --- src/apps/debugger/dwarf/Jamfile | 3 --- 13 files changed, 39 deletions(-) diff --git a/src/apps/debuganalyzer/gui/Jamfile b/src/apps/debuganalyzer/gui/Jamfile index a3b7e5bcab..fafe2552a8 100644 --- a/src/apps/debuganalyzer/gui/Jamfile +++ b/src/apps/debuganalyzer/gui/Jamfile @@ -5,9 +5,6 @@ UsePrivateSystemHeaders ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_gui.o : AbstractGeneralPage.cpp diff --git a/src/apps/debuganalyzer/gui/chart/Jamfile b/src/apps/debuganalyzer/gui/chart/Jamfile index b24915372a..6a611cdc0e 100644 --- a/src/apps/debuganalyzer/gui/chart/Jamfile +++ b/src/apps/debuganalyzer/gui/chart/Jamfile @@ -4,9 +4,6 @@ UsePrivateHeaders shared ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_gui_chart.o : BigtimeChartAxisLegendSource.cpp diff --git a/src/apps/debuganalyzer/gui/main_window/Jamfile b/src/apps/debuganalyzer/gui/main_window/Jamfile index d045a19373..2479331aee 100644 --- a/src/apps/debuganalyzer/gui/main_window/Jamfile +++ b/src/apps/debuganalyzer/gui/main_window/Jamfile @@ -7,9 +7,6 @@ UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; UseHeaders [ FDirName $(HAIKU_TOP) src apps debugger util ] ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_gui_main_window.o : GeneralPage.cpp diff --git a/src/apps/debuganalyzer/gui/table/Jamfile b/src/apps/debuganalyzer/gui/table/Jamfile index f55bca6d11..da838b98b7 100644 --- a/src/apps/debuganalyzer/gui/table/Jamfile +++ b/src/apps/debuganalyzer/gui/table/Jamfile @@ -5,9 +5,6 @@ UsePrivateSystemHeaders ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_gui_table.o : AbstractTable.cpp diff --git a/src/apps/debuganalyzer/gui/thread_window/Jamfile b/src/apps/debuganalyzer/gui/thread_window/Jamfile index 3e171d0251..5a96ee698f 100644 --- a/src/apps/debuganalyzer/gui/thread_window/Jamfile +++ b/src/apps/debuganalyzer/gui/thread_window/Jamfile @@ -5,9 +5,6 @@ UsePrivateSystemHeaders ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_gui_thread_window.o : ActivityPage.cpp diff --git a/src/apps/debuganalyzer/model/Jamfile b/src/apps/debuganalyzer/model/Jamfile index 165c2f6d5a..22e4db74f2 100644 --- a/src/apps/debuganalyzer/model/Jamfile +++ b/src/apps/debuganalyzer/model/Jamfile @@ -5,9 +5,6 @@ UsePrivateSystemHeaders ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_model.o : Model.cpp diff --git a/src/apps/debuganalyzer/model_loader/Jamfile b/src/apps/debuganalyzer/model_loader/Jamfile index ed9888b115..af860197e9 100644 --- a/src/apps/debuganalyzer/model_loader/Jamfile +++ b/src/apps/debuganalyzer/model_loader/Jamfile @@ -5,9 +5,6 @@ UsePrivateSystemHeaders ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_model_loader.o : AbstractModelLoader.cpp diff --git a/src/apps/debuganalyzer/util/Jamfile b/src/apps/debuganalyzer/util/Jamfile index 8a5316a3f7..fd6ab0cbdf 100644 --- a/src/apps/debuganalyzer/util/Jamfile +++ b/src/apps/debuganalyzer/util/Jamfile @@ -5,9 +5,6 @@ UsePrivateSystemHeaders ; UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - MergeObject DebugAnalyzer_util.o : DataSource.cpp diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 56f1ed8577..ac9212f809 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -1,8 +1,5 @@ SubDir HAIKU_TOP src apps debugger ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ; # for syscall_numbers.h diff --git a/src/apps/debugger/arch/x86/disasm/Jamfile b/src/apps/debugger/arch/x86/disasm/Jamfile index 0b40f9f7e0..284eac6400 100644 --- a/src/apps/debugger/arch/x86/disasm/Jamfile +++ b/src/apps/debugger/arch/x86/disasm/Jamfile @@ -1,8 +1,5 @@ SubDir HAIKU_TOP src apps debugger arch x86 disasm ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - UsePrivateHeaders shared ; UseHeaders [ LibraryHeaders udis86 ] ; diff --git a/src/apps/debugger/arch/x86_64/disasm/Jamfile b/src/apps/debugger/arch/x86_64/disasm/Jamfile index 7424d3d780..9b1289e0cf 100644 --- a/src/apps/debugger/arch/x86_64/disasm/Jamfile +++ b/src/apps/debugger/arch/x86_64/disasm/Jamfile @@ -1,8 +1,5 @@ SubDir HAIKU_TOP src apps debugger arch x86_64 disasm ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - UsePrivateHeaders shared ; UseHeaders [ LibraryHeaders udis86 ] ; diff --git a/src/apps/debugger/demangler/Jamfile b/src/apps/debugger/demangler/Jamfile index 613c6aace5..d71c877cf9 100644 --- a/src/apps/debugger/demangler/Jamfile +++ b/src/apps/debugger/demangler/Jamfile @@ -1,8 +1,5 @@ SubDir HAIKU_TOP src apps debugger demangler ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons kernel debugger demangle ] ; diff --git a/src/apps/debugger/dwarf/Jamfile b/src/apps/debugger/dwarf/Jamfile index 0efb29c52e..4cf6b78281 100644 --- a/src/apps/debugger/dwarf/Jamfile +++ b/src/apps/debugger/dwarf/Jamfile @@ -1,8 +1,5 @@ SubDir HAIKU_TOP src apps debugger dwarf ; -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - UsePrivateHeaders kernel shared ; UsePrivateSystemHeaders ; From ef5e0ba9384ca25a5b367806fd0c071dc9337813 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Sun, 15 Sep 2013 03:59:19 +0200 Subject: [PATCH 068/137] ARM: stub out missing int64 atomic functions Also, add an item to the TODO list for this. Really need to figure it out soon... --- docs/develop/ports/arm/todo.txt | 5 ++ src/system/libroot/os/arch/arm/atomic.S | 89 ++++++------------------- 2 files changed, 26 insertions(+), 68 deletions(-) diff --git a/docs/develop/ports/arm/todo.txt b/docs/develop/ports/arm/todo.txt index e49b6c8aa5..9e73bea4ea 100644 --- a/docs/develop/ports/arm/todo.txt +++ b/docs/develop/ports/arm/todo.txt @@ -1,3 +1,8 @@ +* Determine how to handle atomic functions on ARM. + GCC inlines are not supported, since the instructionset is ill-equiped for + this on older (pre-ARMv7) architectures. We possibly have to do something + similar to the linux kernel helper functions for this.... + * Figure out how to get page flags (modified/accessed) and implement it ;) use unmapped/read-only mappings to trigger soft faults for tracking used/modified flags for ARMv5 and ARMv6 diff --git a/src/system/libroot/os/arch/arm/atomic.S b/src/system/libroot/os/arch/arm/atomic.S index 0127fd03e8..795e89961d 100644 --- a/src/system/libroot/os/arch/arm/atomic.S +++ b/src/system/libroot/os/arch/arm/atomic.S @@ -164,83 +164,36 @@ FUNCTION(atomic_get): bx lr FUNCTION_END(atomic_get) +FUNCTION(__sync_fetch_and_add_4): + bx lr +FUNCTION_END(__sync_fetch_and_add_4) /* int64 atomic_add64(vint64 *value, int64 addValue) */ -//FUNCTION(atomic_add64): -// movem.l %d2-%d3/%a2,-(%a7) -// move.l (4,%a7),%a2 -// lea.l (4,%a2),%a1 -// // addValue -// move.l (12,%a7),%d3 /*LSB*/ -// move.l (8,%a7),%d2 /*MSB*/ -//miss5: // old value -// move.l (%a1),%d1 /*LSB*/ -// move.l (%a2),%d0 /*MSB*/ -// add.l %d1,%d3 -// addx.l %d0,%d2 -// cas2.l %d0:%d1,%d2:%d3,(%a2):(%a1) -// bne miss5 -// // return value d0:d1 -// movem.l (%a7)+,%d2-%d3/%a2 -// rts -//FUNCTION_END(atomic_add64) +FUNCTION(atomic_add64): + bx lr +FUNCTION_END(atomic_add64) /* int64 atomic_and64(vint64 *value, int64 andValue) */ -//FUNCTION(atomic_and64): -//FUNCTION_END(atomic_and64) +FUNCTION(atomic_and64): + bx lr +FUNCTION_END(atomic_and64) /* int64 atomic_or64(vint64 *value, int64 orValue) */ -//FUNCTION(atomic_or64): -//FUNCTION_END(atomic_or64) +FUNCTION(atomic_or64): + bx lr +FUNCTION_END(atomic_or64) /* int64 atomic_set64(vint64 *value, int64 newValue) */ -//FUNCTION(atomic_set64): -// movem.l %d2-%d3/%a2,-(%a7) -// move.l (4,%a7),%a2 -// lea.l (4,%a2),%a1 -// // new value -// move.l (12,%a7),%d3 /*LSB*/ -// move.l (8,%a7),%d2 /*MSB*/ -// // old value -// move.l (%a1),%d1 /*LSB*/ -// move.l (%a2),%d0 /*MSB*/ -//miss8: cas2.l %d0:%d1,%d2:%d3,(%a2):(%a1) -// bne miss8 -// // return value d0:d1 -// movem.l (%a7)+,%d2-%d3/%a2 -// rts -//FUNCTION_END(atomic_set64) +FUNCTION(atomic_set64): + bx lr +FUNCTION_END(atomic_set64) /* int64 atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst) */ -//FUNCTION(atomic_test_and_set64): -// movem.l %d2-%d3/%a2,-(%a7) -// move.l (4,%a7),%a2 -// lea.l (4,%a2),%a1 -// // new value -// move.l (12,%a7),%d3 /*LSB*/ -// move.l (8,%a7),%d2 /*MSB*/ -// // test against value -// move.l (20,%a7),%d1 /*LSB*/ -// move.l (16,%a7),%d0 /*MSB*/ -// cas2.l %d0:%d1,%d2:%d3,(%a2):(%a1) -// // return value d0:d1 -// movem.l (%a7)+,%d2-%d3/%a2 -// rts -//FUNCTION_END(atomic_test_and_set64) +FUNCTION(atomic_test_and_set64): + bx lr +FUNCTION_END(atomic_test_and_set64) /* int64 atomic_get64(vint64 *value) */ -//FUNCTION(atomic_get64): -// movem.l %d2-%d3/%a2,-(%a7) -// move.l (4,%a7),%a2 -// lea.l (4,%a2),%a1 -// move.l (%a1),%d1 /*LSB*/ -// move.l (%a2),%d0 /*MSB*/ -// move.l %d1,%d3 -// move.l %d0,%d2 -// // we must use cas... so we change to the same value if matching, -// // else we get the correct one anyway -// cas2.l %d0:%d1,%d2:%d3,(%a2):(%a1) -// // return value -// movem.l (%a7)+,%d2-%d3/%a2 -// rts -//FUNCTION_END(atomic_get64) +FUNCTION(atomic_get64): + bx lr +FUNCTION_END(atomic_get64) From a1d69688489ec16dd2fc144d4553c2e4c653ea2a Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Sun, 15 Sep 2013 04:39:37 +0200 Subject: [PATCH 069/137] ARM: stub out makebootable so we can build a full haiku-image --- src/bin/makebootable/platform/u-boot/Jamfile | 3 +++ src/bin/makebootable/platform/u-boot/makebootable.cpp | 6 ++++++ src/tools/makebootable/platform/u-boot/Jamfile | 3 +++ 3 files changed, 12 insertions(+) create mode 100644 src/bin/makebootable/platform/u-boot/Jamfile create mode 100644 src/bin/makebootable/platform/u-boot/makebootable.cpp create mode 100644 src/tools/makebootable/platform/u-boot/Jamfile diff --git a/src/bin/makebootable/platform/u-boot/Jamfile b/src/bin/makebootable/platform/u-boot/Jamfile new file mode 100644 index 0000000000..e2e9f95c36 --- /dev/null +++ b/src/bin/makebootable/platform/u-boot/Jamfile @@ -0,0 +1,3 @@ +SubDir HAIKU_TOP src bin makebootable platform u-boot ; + +BinCommand makebootable : makebootable.cpp ; diff --git a/src/bin/makebootable/platform/u-boot/makebootable.cpp b/src/bin/makebootable/platform/u-boot/makebootable.cpp new file mode 100644 index 0000000000..8d3ab2762f --- /dev/null +++ b/src/bin/makebootable/platform/u-boot/makebootable.cpp @@ -0,0 +1,6 @@ +int +main() +{ + return 0; +} + diff --git a/src/tools/makebootable/platform/u-boot/Jamfile b/src/tools/makebootable/platform/u-boot/Jamfile new file mode 100644 index 0000000000..237a8a8eb2 --- /dev/null +++ b/src/tools/makebootable/platform/u-boot/Jamfile @@ -0,0 +1,3 @@ +SubDir HAIKU_TOP src tools makebootable platform u-boot ; + +BuildPlatformMain makebootable : makebootable.cpp : $(HOST_LIBSTDC++) ; From c00e42d577c7034dc92729d8d76f5bae7577463f Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Sun, 15 Sep 2013 04:55:07 +0200 Subject: [PATCH 070/137] u-boot: make sure host makebootable builds too Somehow missed these few lines in my last commit. --- src/tools/makebootable/platform/u-boot/Jamfile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/tools/makebootable/platform/u-boot/Jamfile b/src/tools/makebootable/platform/u-boot/Jamfile index 237a8a8eb2..eac99f00d3 100644 --- a/src/tools/makebootable/platform/u-boot/Jamfile +++ b/src/tools/makebootable/platform/u-boot/Jamfile @@ -1,3 +1,12 @@ SubDir HAIKU_TOP src tools makebootable platform u-boot ; +SEARCH_SOURCE + += [ FDirName $(HAIKU_TOP) src bin makebootable platform u-boot ] ; + +BuildPlatformMain makebootable : + makebootable.cpp + $(hostPlatformSources) + : $(HOST_LIBBE) $(HOST_LIBSTDC++) $(HOST_LIBSUPC++) +; + BuildPlatformMain makebootable : makebootable.cpp : $(HOST_LIBSTDC++) ; From b9fa914d1e42be8611aacbe62977c998bb0b1c78 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Sun, 15 Sep 2013 07:26:02 +0200 Subject: [PATCH 071/137] norflash: Add hack to hide start of NOR flash This is a workaround for hiding U-Boot that is stored in the first 2 128k blocks, so we can put a BFS image into NOR to boot from (since we do not have support for SD/MMC yet in Haiku). When manually putting a BFS filesystem at block 3 we actually get right up to the point where BootScript is attempted to be executed! --- src/add-ons/kernel/drivers/disk/norflash/norflash.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp b/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp index 37b9186c1e..4bd20bd48c 100644 --- a/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp +++ b/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp @@ -31,7 +31,10 @@ #define NORFLASH_ADDR 0x00000000 +#define SIZE_IN_BLOCKS 256 +/* Hide the start of NOR since U-Boot lives there */ +#define HIDDEN_BLOCKS 2 struct nor_driver_info { device_node *node; @@ -54,7 +57,7 @@ nor_init_device(void *_info, void **_cookie) info->mapped = NULL; info->blocksize = 128 * 1024; - info->totalsize = info->blocksize * 256; + info->totalsize = (SIZE_IN_BLOCKS - HIDDEN_BLOCKS) * info->blocksize; info->id = map_physical_memory("NORFlash", NORFLASH_ADDR, info->totalsize, B_ANY_KERNEL_ADDRESS, B_READ_AREA, &info->mapped); if (info->id < 0) @@ -139,6 +142,8 @@ nor_read(void *_cookie, off_t position, void *data, size_t *numbytes) nor_driver_info *info = (nor_driver_info*)_cookie; TRACE("read(%Ld,%lu)\n", position, *numbytes); + position += HIDDEN_BLOCKS * info->blocksize; + if (position + *numbytes > info->totalsize) *numbytes = info->totalsize - (position + *numbytes); From b119365b2198a23308fed21af0145dcdc3aa272a Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Sun, 15 Sep 2013 11:21:01 +0200 Subject: [PATCH 072/137] usb_disk: returns B_DEV_NOT_READY for SCSI_SENSE_KEY_NOT_READY ...instead of B_DEV_NO_MEDIA. The latter seems to imply we stop testing the unit is ready in usb_disk_device_added(). Based on a patch provided by markh in #9589. --- src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp index ddc02b4898..87383f03fb 100644 --- a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp @@ -487,7 +487,7 @@ usb_disk_request_sense(device_lun *lun) parameter.additional_sense_code_qualifier); lun->media_present = false; usb_disk_reset_capacity(lun); - return B_DEV_NO_MEDIA; + return B_DEV_NOT_READY; case SCSI_SENSE_KEY_DATA_PROTECT: TRACE_ALWAYS("request_sense: write protected\n"); From b9f280cb8c3e73623e7c772c14b7ed8bc8ee6754 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Sun, 15 Sep 2013 11:31:41 +0200 Subject: [PATCH 073/137] ntfs: make sure our confidence is higher then the intel partition add-on This as the intel partition addon just does a very weak test, and the NTFS test is much safer. This prevents NTFS filesystems that have a valid boot sector signature but no partition table, from being picked up by the intel partition table add-on instead of the ntfs add-on. Patch provided by markh, thanks! --- src/add-ons/kernel/file_systems/ntfs/fs_func.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/add-ons/kernel/file_systems/ntfs/fs_func.c b/src/add-ons/kernel/file_systems/ntfs/fs_func.c index b7ee6ead0d..430922da9c 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fs_func.c +++ b/src/add-ons/kernel/file_systems/ntfs/fs_func.c @@ -274,7 +274,9 @@ fs_identify_partition(int fd, partition_data *partition, void **_cookie) *_cookie = cookie; - return 0.8f; + // Make sure we return a higher number than the intel partition check + // as this one is more accurate. + return 0.82f; } From 4ace94e6b11489dab205f4d954538f17dec6a33b Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Sun, 15 Sep 2013 11:45:40 +0200 Subject: [PATCH 074/137] beos_mime: add sniffer rule for .mp3 files Patch from markh (ticket #9790), thanks! --- src/data/beos_mime/audio/mpeg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/data/beos_mime/audio/mpeg b/src/data/beos_mime/audio/mpeg index c23a60db1a..05ba846fdc 100644 --- a/src/data/beos_mime/audio/mpeg +++ b/src/data/beos_mime/audio/mpeg @@ -12,3 +12,5 @@ resource(5, "META:EXTENS") message(234) { "extensions" = "MP3", "type" = "audio/mpeg" }; + +resource(6, "META:SNIFF_RULE") "0.50 (0xfffb|0xfffa|\"ID3\")"; From c11cdf8d88cd93f11f2711623e17276ddaa57a17 Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Sun, 15 Sep 2013 14:39:56 +0200 Subject: [PATCH 075/137] dpc: fix comments spelling. --- src/add-ons/kernel/generic/dpc/dpc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/add-ons/kernel/generic/dpc/dpc.c b/src/add-ons/kernel/generic/dpc/dpc.c index 4b09253542..4557972c18 100644 --- a/src/add-ons/kernel/generic/dpc/dpc.c +++ b/src/add-ons/kernel/generic/dpc/dpc.c @@ -64,7 +64,7 @@ dpc_thread(void *arg) } // Let's finish the pending DPCs, if any. - // Otherwise, resource could leaks... + // Otherwise, resource could leak... while (queue->count--) { dpc = queue->slots[queue->head]; queue->head = (queue->head + 1) % queue->size; @@ -135,7 +135,7 @@ delete_dpc_queue(void *handle) if (!queue) return B_BAD_VALUE; - // Close the queue: queue_dpc() should knows we're closing: + // Close the queue: queue_dpc() should know we're closing: former = disable_interrupts(); acquire_spinlock(&queue->lock); @@ -186,8 +186,8 @@ queue_dpc(void *handle, dpc_func function, void *arg) restore_interrupts(former); if (status == B_OK) - // Wake up the corresponding dpc thead - // Notice that interrupt handlers should returns B_INVOKE_SCHEDULER to + // Wake up the corresponding dpc thread + // Notice that interrupt handlers should return B_INVOKE_SCHEDULER to // shorten DPC latency as much as possible... status = release_sem_etc(queue->wakeup_sem, 1, B_DO_NOT_RESCHEDULE); From 92d6655640a788eea5faacbabe1aaed78da7ee11 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sun, 15 Sep 2013 15:32:19 +0200 Subject: [PATCH 076/137] Debugger: Implement #9960. - DebugReportGenerator now retrieves and dumps disassembly for the crashing function up to the crashing line. --- .../controllers/DebugReportGenerator.cpp | 87 ++++++++++++++++++- .../controllers/DebugReportGenerator.h | 9 +- 2 files changed, 92 insertions(+), 4 deletions(-) diff --git a/src/apps/debugger/controllers/DebugReportGenerator.cpp b/src/apps/debugger/controllers/DebugReportGenerator.cpp index 66ac0f2966..60cdba9026 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.cpp +++ b/src/apps/debugger/controllers/DebugReportGenerator.cpp @@ -18,12 +18,15 @@ #include "AreaInfo.h" #include "CpuState.h" #include "DebuggerInterface.h" +#include "DisassembledCode.h" +#include "FunctionInstance.h" #include "Image.h" #include "MessageCodes.h" #include "Register.h" #include "SemaphoreInfo.h" #include "StackFrame.h" #include "StackTrace.h" +#include "Statement.h" #include "StringUtils.h" #include "SystemInfo.h" #include "Team.h" @@ -51,7 +54,8 @@ DebugReportGenerator::DebugReportGenerator(::Team* team, fWaitingNode(NULL), fCurrentBlock(NULL), fBlockRetrievalStatus(B_OK), - fTraceWaitingThread(NULL) + fTraceWaitingThread(NULL), + fSourceWaitingFunction(NULL) { fTeam->AddListener(this); fArchitecture->AcquireReference(); @@ -204,6 +208,20 @@ DebugReportGenerator::ValueNodeValueChanged(ValueNode* node) } +void +DebugReportGenerator::FunctionSourceCodeChanged(Function* function) +{ + AutoLocker< ::Team> teamLocker(fTeam); + if (function == fSourceWaitingFunction) { + if (function->FirstInstance()->SourceCodeState() + == FUNCTION_SOURCE_LOADED + || function->FirstInstance()->SourceCodeState() + == FUNCTION_SOURCE_UNAVAILABLE) { + release_sem(fTeamDataSem); + } + } +} + status_t DebugReportGenerator::_GenerateReportHeader(BString& _output) { @@ -452,9 +470,12 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output, && frame->CountLocalVariables() == 0) { // only dump the topmost frame if (i == 0) { + locker.Unlock(); + _DumpFunctionDisassembly(_output, frame->InstructionPointer()); _DumpStackFrameMemory(_output, thread->GetCpuState(), frame->FrameAddress(), thread->GetTeam()->GetArchitecture() ->StackGrowthDirection()); + locker.Lock(); } continue; } @@ -495,6 +516,66 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output, } +void +DebugReportGenerator::_DumpFunctionDisassembly(BString& _output, + target_addr_t instructionPointer) +{ + AutoLocker< ::Team> teamLocker(fTeam); + BString data; + FunctionInstance* instance = NULL; + Statement* statement = NULL; + status_t error = fTeam->GetStatementAtAddress(instructionPointer, instance, + statement); + if (error != B_OK) { + data.SetToFormat("Unable to retrieve disassembly for IP %#" B_PRIx64 + ": %s\n", instructionPointer, strerror(error)); + _output << data; + return; + } + + DisassembledCode* code = instance->GetSourceCode(); + Function* function = instance->GetFunction(); + if (code == NULL) { + switch (function->SourceCodeState()) { + case FUNCTION_SOURCE_NOT_LOADED: + function->AddListener(this); + fSourceWaitingFunction = function; + fListener->FunctionSourceCodeRequested(instance, true); + // fall through + case FUNCTION_SOURCE_LOADING: + { + teamLocker.Unlock(); + error = acquire_sem(fTeamDataSem); + if (error != B_OK) + return; + teamLocker.Lock(); + break; + } + default: + return; + } + + if (instance->SourceCodeState() == FUNCTION_SOURCE_UNAVAILABLE) + return; + + error = fTeam->GetStatementAtAddress(instructionPointer, instance, + statement); + code = instance->GetSourceCode(); + } + + SourceLocation location = statement->StartSourceLocation(); + + _output << "\t\t\tDisassembly:\n"; + for (int32 i = 0; i < location.Line(); i++) { + _output << "\t\t\t\t" << code->LineAt(i); + if (i == location.Line() - 1) + _output << " <--"; + _output << "\n"; + } + _output << "\n"; +} + + void DebugReportGenerator::_DumpStackFrameMemory(BString& _output, CpuState* state, target_addr_t framePointer, uint8 stackDirection) @@ -519,11 +600,11 @@ DebugReportGenerator::_DumpStackFrameMemory(BString& _output, _output << "\t\t\tFrame memory:\n"; if (fBlockRetrievalStatus == B_OK) { - UiUtils::DumpMemory(_output, 3, fCurrentBlock, startAddress, 1, 16, + UiUtils::DumpMemory(_output, 4 , fCurrentBlock, startAddress, 1, 16, endAddress - startAddress); } else { BString data; - data.SetToFormat("\t\t\tUnavailable (%s)\n", strerror( + data.SetToFormat("\t\t\t\tUnavailable (%s)\n", strerror( fBlockRetrievalStatus)); _output += data; } diff --git a/src/apps/debugger/controllers/DebugReportGenerator.h b/src/apps/debugger/controllers/DebugReportGenerator.h index 13746e9502..121bb5a20c 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.h +++ b/src/apps/debugger/controllers/DebugReportGenerator.h @@ -8,6 +8,7 @@ #include +#include "Function.h" #include "Team.h" #include "TeamMemoryBlock.h" #include "ValueNodeContainer.h" @@ -30,7 +31,8 @@ class ValueNodeManager; class DebugReportGenerator : public BLooper, private Team::Listener, - private TeamMemoryBlock::Listener, private ValueNodeContainer::Listener { + private TeamMemoryBlock::Listener, private ValueNodeContainer::Listener, + private Function::Listener { public: DebugReportGenerator(::Team* team, UserInterfaceListener* listener, @@ -58,6 +60,8 @@ private: // ValueNodeContainer::Listener virtual void ValueNodeValueChanged(ValueNode* node); + // Function::Listener + virtual void FunctionSourceCodeChanged(Function* function); private: status_t _GenerateReport(const entry_ref& outputPath); @@ -68,6 +72,8 @@ private: status_t _DumpRunningThreads(BString& _output); status_t _DumpDebuggedThreadInfo(BString& _output, ::Thread* thread); + void _DumpFunctionDisassembly(BString& _output, + target_addr_t instructionPointer); void _DumpStackFrameMemory(BString& _output, CpuState* state, target_addr_t framePointer, @@ -97,6 +103,7 @@ private: TeamMemoryBlock* fCurrentBlock; status_t fBlockRetrievalStatus; ::Thread* fTraceWaitingThread; + Function* fSourceWaitingFunction; }; #endif // DEBUG_REPORT_GENERATOR_H From d2c9f2e651a1dcf3f49f6f2e7141a3743a682072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 15 Sep 2013 17:21:11 +0200 Subject: [PATCH 077/137] HaikuDepot: Use PackageInfoRefs instead of PackageInfos Instead of storing PackageInfo objects directly in the PackageLists, store PackageInfoRefs instead. This makes a lot of operations much cheaper, and it also allows making changes to a PackageInfo (which now exists only once) and have those changes reflect everywhere. In particular, it will be easier to populate some information of the PackageInfo lazily, and to listen for changes on a PackageInfo object. --- src/apps/haiku-depot/MainWindow.cpp | 42 ++++++++++++------------ src/apps/haiku-depot/MainWindow.h | 2 +- src/apps/haiku-depot/Model.cpp | 30 +++++++++-------- src/apps/haiku-depot/Model.h | 4 +-- src/apps/haiku-depot/PackageInfo.cpp | 2 +- src/apps/haiku-depot/PackageInfo.h | 9 +++-- src/apps/haiku-depot/PackageListView.cpp | 19 +++++++---- src/apps/haiku-depot/PackageListView.h | 4 +-- 8 files changed, 62 insertions(+), 50 deletions(-) diff --git a/src/apps/haiku-depot/MainWindow.cpp b/src/apps/haiku-depot/MainWindow.cpp index b7b0552c87..92eaa9c338 100644 --- a/src/apps/haiku-depot/MainWindow.cpp +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -160,9 +160,9 @@ MainWindow::_AdoptModel() void -MainWindow::_AdoptPackage(const PackageInfo& package) +MainWindow::_AdoptPackage(const PackageInfoRef& package) { - fPackageInfoView->SetPackage(package); + fPackageInfoView->SetPackage(*package.Get()); } @@ -183,7 +183,7 @@ MainWindow::_InitDummyModel() DepotInfo depot(B_TRANSLATE("Default")); // WonderBrush - PackageInfo wonderbrush( + PackageInfoRef wonderbrush(new(std::nothrow) PackageInfo( BitmapRef(new SharedBitmap(601), true), "WonderBrush", "2.1.2", @@ -196,24 +196,24 @@ MainWindow::_InitDummyModel() "WonderBrush is YellowBites' software for doing graphics design " "on Haiku. It combines many great under-the-hood features with " "powerful tools and an efficient and intuitive interface.", - "2.1.2 - Initial Haiku release."); - wonderbrush.AddUserRating( + "2.1.2 - Initial Haiku release."), true); + wonderbrush->AddUserRating( UserRating(UserInfo("humdinger"), 4.5f, "Awesome!", "en", "2.1.2", 0, 0) ); - wonderbrush.AddUserRating( + wonderbrush->AddUserRating( UserRating(UserInfo("bonefish"), 5.0f, "The best!", "en", "2.1.2", 3, 1) ); - wonderbrush.AddScreenshot( + wonderbrush->AddScreenshot( BitmapRef(new SharedBitmap(603), true)); - wonderbrush.AddCategory(fModel.CategoryGraphics()); - wonderbrush.AddCategory(fModel.CategoryProductivity()); + wonderbrush->AddCategory(fModel.CategoryGraphics()); + wonderbrush->AddCategory(fModel.CategoryProductivity()); depot.AddPackage(wonderbrush); // Paladin - PackageInfo paladin( + PackageInfoRef paladin(new(std::nothrow) PackageInfo( BitmapRef(new SharedBitmap(602), true), "Paladin", "1.2.0", @@ -227,30 +227,30 @@ MainWindow::_InitDummyModel() "The interface is streamlined, it has some features sorely " "missing from BeIDE, like running a project in the Terminal, " "and has a bundled text editor based upon Pe.", - ""); - paladin.AddUserRating( + ""), true); + paladin->AddUserRating( UserRating(UserInfo("stippi"), 3.5f, "Could be more integrated from the sounds of it.", "en", "1.2.0", 0, 1) ); - paladin.AddUserRating( + paladin->AddUserRating( UserRating(UserInfo("mmadia"), 5.0f, "It rocks! Give a try", "en", "1.1.0", 1, 0) ); - paladin.AddUserRating( + paladin->AddUserRating( UserRating(UserInfo("bonefish"), 2.0f, "It just needs to use my jam-rewrite 'ham' and it will be great.", "en", "1.1.0", 3, 1) ); - paladin.AddScreenshot( + paladin->AddScreenshot( BitmapRef(new SharedBitmap(605), true)); - paladin.AddCategory(fModel.CategoryDevelopment()); + paladin->AddCategory(fModel.CategoryDevelopment()); depot.AddPackage(paladin); // Sequitur - PackageInfo sequitur( + PackageInfoRef sequitur(new(std::nothrow) PackageInfo( BitmapRef(new SharedBitmap(604), true), "Sequitur", "2.1.0", @@ -314,8 +314,8 @@ MainWindow::_InitDummyModel() "pressure events. The new tool Broken Down Line uses this " "filter.\n\n" " * ''Note to filter developers:'' The filter API has changed. You " - "will need to recompile your filters."); - sequitur.AddUserRating( + "will need to recompile your filters."), true); + sequitur->AddUserRating( UserRating(UserInfo("pete"), 4.5f, "I can weave a web of sound! And it connects to PatchBay. Check " "it out, I can wholeheartly recommend this app!! This rating " @@ -326,14 +326,14 @@ MainWindow::_InitDummyModel() "please the programmer with the text layouting and scrolling of " "long ratings!", "en", "2.1.0", 4, 1) ); - sequitur.AddUserRating( + sequitur->AddUserRating( UserRating(UserInfo("stippi"), 3.5f, "It seems very capable. Still runs fine on Haiku. The interface " "is composed of many small, hard to click items. But you can " "configure a tool for each mouse button, which is great for the " "work flow.", "en", "2.1.0", 2, 1) ); - sequitur.AddCategory(fModel.CategoryAudio()); + sequitur->AddCategory(fModel.CategoryAudio()); depot.AddPackage(sequitur); diff --git a/src/apps/haiku-depot/MainWindow.h b/src/apps/haiku-depot/MainWindow.h index 694f32dc7b..b848741f9a 100644 --- a/src/apps/haiku-depot/MainWindow.h +++ b/src/apps/haiku-depot/MainWindow.h @@ -35,7 +35,7 @@ private: void _BuildMenu(BMenuBar* menuBar); void _AdoptModel(); - void _AdoptPackage(const PackageInfo& package); + void _AdoptPackage(const PackageInfoRef& package); void _ClearPackage(); void _InitDummyModel(); diff --git a/src/apps/haiku-depot/Model.cpp b/src/apps/haiku-depot/Model.cpp index 6557bd16b6..a6c16f5917 100644 --- a/src/apps/haiku-depot/Model.cpp +++ b/src/apps/haiku-depot/Model.cpp @@ -24,7 +24,7 @@ PackageFilter::~PackageFilter() class AnyFilter : public PackageFilter { public: - virtual bool AcceptsPackage(const PackageInfo& package) const + virtual bool AcceptsPackage(const PackageInfoRef& package) const { return true; } @@ -39,7 +39,7 @@ public: { } - virtual bool AcceptsPackage(const PackageInfo& package) const + virtual bool AcceptsPackage(const PackageInfoRef& package) const { // TODO: Maybe a PackageInfo ought to know the Depot it came from? // But right now the same package could theoretically be provided @@ -68,9 +68,11 @@ public: { } - virtual bool AcceptsPackage(const PackageInfo& package) const + virtual bool AcceptsPackage(const PackageInfoRef& package) const { - const CategoryList& categories = package.Categories(); + if (package.Get() == NULL) + return false; + const CategoryList& categories = package->Categories(); for (int i = categories.CountItems() - 1; i >= 0; i--) { const CategoryRef& category = categories.ItemAtFast(i); if (category.Get() == NULL) @@ -94,7 +96,7 @@ public: { } - virtual bool AcceptsPackage(const PackageInfo& package) const + virtual bool AcceptsPackage(const PackageInfoRef& package) const { return fPackageList.Contains(package); } @@ -114,7 +116,7 @@ public: { } - virtual bool AcceptsPackage(const PackageInfo& package) const + virtual bool AcceptsPackage(const PackageInfoRef& package) const { return fPackageListA.Contains(package) || fPackageListB.Contains(package); @@ -146,15 +148,17 @@ public: } } - virtual bool AcceptsPackage(const PackageInfo& package) const + virtual bool AcceptsPackage(const PackageInfoRef& package) const { + if (package.Get() == NULL) + return false; // Every search term must be found in one of the package texts for (int32 i = fSearchTerms.CountItems() - 1; i >= 0; i--) { const BString& term = fSearchTerms.ItemAtFast(i); - if (!_TextContains(package.Title(), term) - && !_TextContains(package.Publisher().Name(), term) - && !_TextContains(package.ShortDescription(), term) - && !_TextContains(package.FullDescription(), term)) { + if (!_TextContains(package->Title(), term) + && !_TextContains(package->Publisher().Name(), term) + && !_TextContains(package->ShortDescription(), term) + && !_TextContains(package->FullDescription(), term)) { return false; } } @@ -263,7 +267,7 @@ Model::CreatePackageList() const const PackageList& packages = depot.Packages(); for (int32 j = 0; j < packages.CountItems(); j++) { - const PackageInfo& package = packages.ItemAtFast(j); + const PackageInfoRef& package = packages.ItemAtFast(j); if (fCategoryFilter->AcceptsPackage(package) && fSearchTermsFilter->AcceptsPackage(package)) { resultList.Add(package); @@ -283,7 +287,7 @@ Model::AddDepot(const DepotInfo& depot) void -Model::SetPackageState(const PackageInfo& package, PackageState state) +Model::SetPackageState(const PackageInfoRef& package, PackageState state) { switch (state) { default: diff --git a/src/apps/haiku-depot/Model.h b/src/apps/haiku-depot/Model.h index 87ff560d3e..390c0a6c39 100644 --- a/src/apps/haiku-depot/Model.h +++ b/src/apps/haiku-depot/Model.h @@ -14,7 +14,7 @@ public: virtual ~PackageFilter(); virtual bool AcceptsPackage( - const PackageInfo& package) const = 0; + const PackageInfoRef& package) const = 0; }; typedef BReference PackageFilterRef; @@ -55,7 +55,7 @@ public: { return fProgressCategories; } void SetPackageState( - const PackageInfo& package, + const PackageInfoRef& package, PackageState state); // Configure PackageFilters diff --git a/src/apps/haiku-depot/PackageInfo.cpp b/src/apps/haiku-depot/PackageInfo.cpp index 7172b80929..6b78f98cb0 100644 --- a/src/apps/haiku-depot/PackageInfo.cpp +++ b/src/apps/haiku-depot/PackageInfo.cpp @@ -640,7 +640,7 @@ DepotInfo::operator!=(const DepotInfo& other) const bool -DepotInfo::AddPackage(const PackageInfo& package) +DepotInfo::AddPackage(const PackageInfoRef& package) { return fPackages.Add(package); } diff --git a/src/apps/haiku-depot/PackageInfo.h b/src/apps/haiku-depot/PackageInfo.h index c66aecd4ee..d2bc66a0a8 100644 --- a/src/apps/haiku-depot/PackageInfo.h +++ b/src/apps/haiku-depot/PackageInfo.h @@ -181,7 +181,7 @@ typedef BReference CategoryRef; typedef List CategoryList; -class PackageInfo { +class PackageInfo : public BReferenceable { public: PackageInfo(); PackageInfo(const BitmapRef& icon, @@ -239,7 +239,10 @@ private: }; -typedef List PackageList; +typedef BReference PackageInfoRef; + + +typedef List PackageList; enum PackageState { @@ -266,7 +269,7 @@ public: const PackageList& Packages() const { return fPackages; } - bool AddPackage(const PackageInfo& package); + bool AddPackage(const PackageInfoRef& package); private: BString fName; diff --git a/src/apps/haiku-depot/PackageListView.cpp b/src/apps/haiku-depot/PackageListView.cpp index 332a64bf3f..f21f9f85b1 100644 --- a/src/apps/haiku-depot/PackageListView.cpp +++ b/src/apps/haiku-depot/PackageListView.cpp @@ -80,13 +80,13 @@ private: class PackageRow : public BRow { typedef BRow Inherited; public: - PackageRow(const PackageInfo& package); + PackageRow(const PackageInfoRef& package); - const PackageInfo& Package() const + const PackageInfoRef& Package() const { return fPackage; } private: - PackageInfo fPackage; + PackageInfoRef fPackage; }; @@ -374,11 +374,16 @@ enum { }; -PackageRow::PackageRow(const PackageInfo& package) +PackageRow::PackageRow(const PackageInfoRef& packageRef) : Inherited(ceilf(be_plain_font->Size() * 1.8f)), - fPackage(package) + fPackage(packageRef) { + if (packageRef.Get() == NULL) + return; + + const PackageInfo& package = *packageRef.Get(); + // Package icon and title // NOTE: The icon BBitmap is referenced by the fPackage member. const BBitmap* icon = NULL; @@ -553,7 +558,7 @@ PackageListView::SelectionChanged() void -PackageListView::AddPackage(const PackageInfo& package) +PackageListView::AddPackage(const PackageInfoRef& package) { PackageRow* packageRow = _FindRow(package); @@ -575,7 +580,7 @@ PackageListView::AddPackage(const PackageInfo& package) PackageRow* -PackageListView::_FindRow(const PackageInfo& package, PackageRow* parent) +PackageListView::_FindRow(const PackageInfoRef& package, PackageRow* parent) { for (int32 i = CountRows(parent) - 1; i >= 0; i--) { PackageRow* row = dynamic_cast(RowAt(i, parent)); diff --git a/src/apps/haiku-depot/PackageListView.h b/src/apps/haiku-depot/PackageListView.h index 9ffd5760c1..86fdd714c9 100644 --- a/src/apps/haiku-depot/PackageListView.h +++ b/src/apps/haiku-depot/PackageListView.h @@ -29,10 +29,10 @@ public: virtual void SelectionChanged(); - void AddPackage(const PackageInfo& package); + void AddPackage(const PackageInfoRef& package); private: - PackageRow* _FindRow(const PackageInfo& package, + PackageRow* _FindRow(const PackageInfoRef& package, PackageRow* parent = NULL); private: class ItemCountView; From d1d48f6483357fe66a04014eb35408c0af27d225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 15 Sep 2013 17:24:15 +0200 Subject: [PATCH 078/137] HaikuDepot: Add interface for PackageInfoListener. Also defines PackageInfoEvent. --- src/apps/haiku-depot/Jamfile | 1 + src/apps/haiku-depot/PackageInfoListener.cpp | 84 ++++++++++++++++++++ src/apps/haiku-depot/PackageInfoListener.h | 54 +++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 src/apps/haiku-depot/PackageInfoListener.cpp create mode 100644 src/apps/haiku-depot/PackageInfoListener.h diff --git a/src/apps/haiku-depot/Jamfile b/src/apps/haiku-depot/Jamfile index 7788c34840..65196d0261 100644 --- a/src/apps/haiku-depot/Jamfile +++ b/src/apps/haiku-depot/Jamfile @@ -38,6 +38,7 @@ Application HaikuDepot : MainWindow.cpp Model.cpp PackageInfo.cpp + PackageInfoListener.cpp PackageInfoView.cpp PackageListView.cpp PackageManager.cpp diff --git a/src/apps/haiku-depot/PackageInfoListener.cpp b/src/apps/haiku-depot/PackageInfoListener.cpp new file mode 100644 index 0000000000..36a1277476 --- /dev/null +++ b/src/apps/haiku-depot/PackageInfoListener.cpp @@ -0,0 +1,84 @@ +/* + * Copyright 2013, Stephan Aßmus . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include "PackageInfoListener.h" + +#include + + +// #pragma mark - PackageInfoEvent + + +PackageInfoEvent::PackageInfoEvent() + : + fPackage(), + fChanges(0) +{ +} + + +PackageInfoEvent::PackageInfoEvent(const PackageInfoRef& package, + uint32 changes) + : + fPackage(package), + fChanges(changes) +{ +} + + +PackageInfoEvent::PackageInfoEvent(const PackageInfoEvent& other) + : + fPackage(other.fPackage), + fChanges(other.fChanges) +{ +} + + +PackageInfoEvent::~PackageInfoEvent() +{ +} + + +bool +PackageInfoEvent::operator==(const PackageInfoEvent& other) +{ + if (this == &other) + return true; + + return fPackage == other.fPackage + && fChanges == other.fChanges; +} + + +bool +PackageInfoEvent::operator!=(const PackageInfoEvent& other) +{ + return !(*this == other); +} + + +PackageInfoEvent& +PackageInfoEvent::operator=(const PackageInfoEvent& other) +{ + if (this != &other) { + fPackage = other.fPackage; + fChanges = other.fChanges; + } + + return *this; +} + + +// #pragma mark - PackageInfoListener + + +PackageInfoListener::PackageInfoListener() +{ +} + + +PackageInfoListener::~PackageInfoListener() +{ +} diff --git a/src/apps/haiku-depot/PackageInfoListener.h b/src/apps/haiku-depot/PackageInfoListener.h new file mode 100644 index 0000000000..1dcde5c6b7 --- /dev/null +++ b/src/apps/haiku-depot/PackageInfoListener.h @@ -0,0 +1,54 @@ +/* + * Copyright 2013, Stephan Aßmus . + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef PACKAGE_INFO_LISTENER_H +#define PACKAGE_INFO_LISTENER_H + + +#include "PackageInfo.h" + + +enum { + PKG_CHANGED_DESCRIPTION = 1 << 0, + PKG_CHANGED_RATINGS = 1 << 1, + PKG_CHANGED_SCREENSHOTS = 1 << 2, + // ... +}; + + +class PackageInfoEvent { +public: + PackageInfoEvent(); + PackageInfoEvent(const PackageInfoRef& package, + uint32 changes); + PackageInfoEvent(const PackageInfoEvent& other); + virtual ~PackageInfoEvent(); + + bool operator==(const PackageInfoEvent& other); + bool operator!=(const PackageInfoEvent& other); + PackageInfoEvent& operator=(const PackageInfoEvent& other); + + inline const PackageInfoRef& Package() const + { return fPackage; } + + inline uint32 Changes() const + { return fChanges; } + +private: + PackageInfoRef fPackage; + uint32 fChanges; +}; + + +class PackageInfoListener { +public: + PackageInfoListener(); + virtual ~PackageInfoListener(); + + virtual void PackageChanged( + const PackageInfoEvent& event) = 0; +}; + + +#endif // PACKAGE_INFO_LISTENER_H From a07d888425a1f4949c4b0f2ca022fe93dd120a6a Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Sun, 15 Sep 2013 15:22:43 +0200 Subject: [PATCH 079/137] hdaudio: check pin sense on init, don't wait for a switch event with headphones plugged on boot, sound was still enabled on speakers. see #9956 --- .../kernel/drivers/audio/hda/hda_codec.cpp | 100 ++++++++++-------- 1 file changed, 54 insertions(+), 46 deletions(-) diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp b/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp index e778ffcbac..b8ff560260 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp @@ -1174,6 +1174,57 @@ hda_codec_switch_init(hda_audio_group* audioGroup) } +static void +hda_codec_check_sense(hda_codec* codec, bool disable) +{ + hda_audio_group* audioGroup = codec->audio_groups[0]; + + for (uint32 i = 0; i < audioGroup->widget_count; i++) { + hda_widget& widget = audioGroup->widgets[i]; + + if (widget.type != WT_PIN_COMPLEX + || !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities) + || CONF_DEFAULT_DEVICE(widget.d.pin.config) + != PIN_DEV_HEAD_PHONE_OUT) + continue; + + corb_t verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id, + VID_GET_PINSENSE, 0); + uint32 response; + hda_send_verbs(audioGroup->codec, &verb, &response, 1); + disable = response & PIN_SENSE_PRESENCE_DETECT; + TRACE("hda: sensed pin widget %ld, %d\n", widget.node_id, disable); + + uint32 ctrl = hda_widget_prepare_pin_ctrl(audioGroup, &widget, + true); + verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id, + VID_SET_PIN_WIDGET_CONTROL, disable ? ctrl : 0); + hda_send_verbs(audioGroup->codec, &verb, NULL, 1); + break; + } + + for (uint32 i = 0; i < audioGroup->widget_count; i++) { + hda_widget& widget = audioGroup->widgets[i]; + + if (widget.type != WT_PIN_COMPLEX + || !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities)) + continue; + + int device = CONF_DEFAULT_DEVICE(widget.d.pin.config); + if (device != PIN_DEV_AUX + && device != PIN_DEV_SPEAKER + && device != PIN_DEV_LINE_OUT) + continue; + + uint32 ctrl = hda_widget_prepare_pin_ctrl(audioGroup, &widget, + true); + corb_t verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id, + VID_SET_PIN_WIDGET_CONTROL, disable ? 0 : ctrl); + hda_send_verbs(audioGroup->codec, &verb, NULL, 1); + } +} + + static status_t hda_codec_switch_handler(hda_codec* codec) { @@ -1182,53 +1233,8 @@ hda_codec_switch_handler(hda_codec* codec) codec->unsol_response_read %= MAX_CODEC_UNSOL_RESPONSES; bool disable = response & 1; - hda_audio_group* audioGroup = codec->audio_groups[0]; - - for (uint32 i = 0; i < audioGroup->widget_count; i++) { - hda_widget& widget = audioGroup->widgets[i]; - - if (widget.type != WT_PIN_COMPLEX - || !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities) - || CONF_DEFAULT_DEVICE(widget.d.pin.config) - != PIN_DEV_HEAD_PHONE_OUT) - continue; - - corb_t verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id, - VID_GET_PINSENSE, 0); - uint32 response; - hda_send_verbs(audioGroup->codec, &verb, &response, 1); - disable = response & PIN_SENSE_PRESENCE_DETECT; - TRACE("hda: sensed pin widget %ld, %d\n", widget.node_id, disable); - - uint32 ctrl = hda_widget_prepare_pin_ctrl(audioGroup, &widget, - true); - verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id, - VID_SET_PIN_WIDGET_CONTROL, disable ? ctrl : 0); - hda_send_verbs(audioGroup->codec, &verb, NULL, 1); - break; - } - - for (uint32 i = 0; i < audioGroup->widget_count; i++) { - hda_widget& widget = audioGroup->widgets[i]; - - if (widget.type != WT_PIN_COMPLEX - || !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities)) - continue; - - int device = CONF_DEFAULT_DEVICE(widget.d.pin.config); - if (device != PIN_DEV_AUX - && device != PIN_DEV_SPEAKER - && device != PIN_DEV_LINE_OUT) - continue; - - uint32 ctrl = hda_widget_prepare_pin_ctrl(audioGroup, &widget, - true); - corb_t verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id, - VID_SET_PIN_WIDGET_CONTROL, disable ? 0 : ctrl); - hda_send_verbs(audioGroup->codec, &verb, NULL, 1); - } + hda_codec_check_sense(codec, disable); } - return B_OK; } @@ -1521,6 +1527,8 @@ hda_codec_new(hda_controller* controller, uint32 codecAddress) } } + hda_codec_check_sense(codec, false); + codec->unsol_response_thread = spawn_kernel_thread( (status_t(*)(void*))hda_codec_switch_handler, "hda_codec_unsol_thread", B_LOW_PRIORITY, codec); From 83f9d3c431b1e0b236690acc62d1eb9e875342a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 15 Sep 2013 17:46:01 +0200 Subject: [PATCH 080/137] HaikuDepot: Added some listener support to PackageInfo --- src/apps/haiku-depot/PackageInfo.cpp | 52 +++++++++++++++++++- src/apps/haiku-depot/PackageInfo.h | 13 +++++ src/apps/haiku-depot/PackageInfoListener.cpp | 2 + src/apps/haiku-depot/PackageInfoListener.h | 11 ++++- 4 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/apps/haiku-depot/PackageInfo.cpp b/src/apps/haiku-depot/PackageInfo.cpp index 6b78f98cb0..2823c77437 100644 --- a/src/apps/haiku-depot/PackageInfo.cpp +++ b/src/apps/haiku-depot/PackageInfo.cpp @@ -535,7 +535,12 @@ PackageInfo::AddCategory(const CategoryRef& category) bool PackageInfo::AddUserRating(const UserRating& rating) { - return fUserRatings.Add(rating); + if (!fUserRatings.Add(rating)) + return false; + + _NotifyListeners(PKG_CHANGED_RATINGS); + + return true; } @@ -584,7 +589,50 @@ PackageInfo::CalculateRatingSummary() const bool PackageInfo::AddScreenshot(const BitmapRef& screenshot) { - return fScreenshots.Add(screenshot); + if (!fScreenshots.Add(screenshot)) + return false; + + _NotifyListeners(PKG_CHANGED_SCREENSHOTS); + + return true; +} + + +bool +PackageInfo::AddListener(const PackageInfoListenerRef& listener) +{ + return fListeners.Add(listener); +} + + +void +PackageInfo::RemoveListener(const PackageInfoListenerRef& listener) +{ + fListeners.Remove(listener); +} + + +void +PackageInfo::_NotifyListeners(uint32 changes) +{ + int count = fListeners.CountItems(); + if (count == 0) + return; + + // Clone list to avoid listeners detaching themselves in notifications + // to screw up the list while iterating it. + PackageListenerList listeners(fListeners); + // Check if it worked: + if (listeners.CountItems () != count) + return; + + PackageInfoEvent event(PackageInfoRef(this), changes); + + for (int i = 0; i < count; i++) { + const PackageInfoListenerRef& listener = listeners.ItemAtFast(i); + if (listener.Get() != NULL) + listener->PackageChanged(event); + } } diff --git a/src/apps/haiku-depot/PackageInfo.h b/src/apps/haiku-depot/PackageInfo.h index d2bc66a0a8..f4f74fa13f 100644 --- a/src/apps/haiku-depot/PackageInfo.h +++ b/src/apps/haiku-depot/PackageInfo.h @@ -10,6 +10,7 @@ #include #include "List.h" +#include "PackageInfoListener.h" class BBitmap; @@ -181,6 +182,9 @@ typedef BReference CategoryRef; typedef List CategoryList; +typedef List PackageListenerList; + + class PackageInfo : public BReferenceable { public: PackageInfo(); @@ -225,6 +229,14 @@ public: const BitmapList& Screenshots() const { return fScreenshots; } + bool AddListener( + const PackageInfoListenerRef& listener); + void RemoveListener( + const PackageInfoListenerRef& listener); + +private: + void _NotifyListeners(uint32 changes); + private: BitmapRef fIcon; BString fTitle; @@ -236,6 +248,7 @@ private: CategoryList fCategories; UserRatingList fUserRatings; BitmapList fScreenshots; + PackageListenerList fListeners; }; diff --git a/src/apps/haiku-depot/PackageInfoListener.cpp b/src/apps/haiku-depot/PackageInfoListener.cpp index 36a1277476..7329c2b365 100644 --- a/src/apps/haiku-depot/PackageInfoListener.cpp +++ b/src/apps/haiku-depot/PackageInfoListener.cpp @@ -7,6 +7,8 @@ #include +#include "PackageInfo.h" + // #pragma mark - PackageInfoEvent diff --git a/src/apps/haiku-depot/PackageInfoListener.h b/src/apps/haiku-depot/PackageInfoListener.h index 1dcde5c6b7..323733ab3a 100644 --- a/src/apps/haiku-depot/PackageInfoListener.h +++ b/src/apps/haiku-depot/PackageInfoListener.h @@ -6,7 +6,7 @@ #define PACKAGE_INFO_LISTENER_H -#include "PackageInfo.h" +#include enum { @@ -17,6 +17,10 @@ enum { }; +class PackageInfo; +typedef BReference PackageInfoRef; + + class PackageInfoEvent { public: PackageInfoEvent(); @@ -41,7 +45,7 @@ private: }; -class PackageInfoListener { +class PackageInfoListener : public BReferenceable { public: PackageInfoListener(); virtual ~PackageInfoListener(); @@ -51,4 +55,7 @@ public: }; +typedef BReference PackageInfoListenerRef; + + #endif // PACKAGE_INFO_LISTENER_H From 81cdbc6ae63980490bb3d3f3717631553a68b75b Mon Sep 17 00:00:00 2001 From: Siarzhuk Zharski Date: Sun, 15 Sep 2013 23:39:44 +0200 Subject: [PATCH 081/137] ListView: More safe ScrollToSelection implementation The Problem was observed in the Time Preferences Zone view - the selection was set inside of TimeZoneView::DoLayout() call on the OutlineListView control that had zero-sized Bounds. After the control was resized the selection stay mainly hidden "under" the upper edge. The Problem looks like generic so should be fixed in the interface kit code. Proposed fix introduces additional check for the scroll position to not cross the top edge of control. --- src/kits/interface/ListView.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/kits/interface/ListView.cpp b/src/kits/interface/ListView.cpp index 5c1b4baa3f..d19cd75b6b 100644 --- a/src/kits/interface/ListView.cpp +++ b/src/kits/interface/ListView.cpp @@ -1037,10 +1037,13 @@ BListView::ScrollToSelection() if (Bounds().Contains(itemFrame)) return; - if (itemFrame.top < Bounds().top) - ScrollTo(itemFrame.left, itemFrame.top); - else - ScrollTo(itemFrame.left, itemFrame.bottom - Bounds().Height()); + float scrollPos = itemFrame.top < Bounds().top ? + itemFrame.top : itemFrame.bottom - Bounds().Height(); + + if (itemFrame.top - scrollPos < Bounds().top) + scrollPos = itemFrame.top; + + ScrollTo(itemFrame.left, scrollPos); } From 367d254419ed612ac5a6b3d4d8c262bc30038c53 Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Mon, 16 Sep 2013 11:47:23 +0200 Subject: [PATCH 082/137] usb_disk: fixes 64bit trace build --- .../drivers/disk/usb/usb_disk/usb_disk.cpp | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp index 87383f03fb..d270798965 100644 --- a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp @@ -267,8 +267,8 @@ usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength, uint32 logicalBlockAddress, uint16 transferLength, void *data, size_t *dataLength, bool directionIn) { - TRACE("operation: lun: %u; op: %u; oplen: %u; lba: %lu; tlen: %u; data: " - "%p; dlen: %p (%lu); in: %c\n", + TRACE("operation: lun: %u; op: %u; oplen: %u; lba: %" B_PRIu32 + "; tlen: %u; data: %p; dlen: %p (%lu); in: %c\n", lun->logical_unit_number, operation, opLength, logicalBlockAddress, transferLength, data, dataLength, dataLength ? *dataLength : 0, directionIn ? 'y' : 'n'); @@ -691,7 +691,7 @@ usb_disk_callback(void *cookie, status_t status, void *data, static status_t usb_disk_device_added(usb_device newDevice, void **cookie) { - TRACE("device_added(0x%08lx)\n", newDevice); + TRACE("device_added(0x%08" B_PRIx32 ")\n", newDevice); disk_device *device = (disk_device *)malloc(sizeof(disk_device)); device->device = newDevice; device->removed = false; @@ -856,7 +856,7 @@ usb_disk_device_added(usb_device newDevice, void **cookie) sprintf(device->luns[i]->name, DEVICE_NAME, device->device_number, i); mutex_unlock(&gDeviceListLock); - TRACE("new device: 0x%08lx\n", (uint32)device); + TRACE("new device: 0x%p\n", device); *cookie = (void *)device; return B_OK; } @@ -865,7 +865,7 @@ usb_disk_device_added(usb_device newDevice, void **cookie) static status_t usb_disk_device_removed(void *cookie) { - TRACE("device_removed(0x%08lx)\n", (uint32)cookie); + TRACE("device_removed(0x%p)\n", cookie); disk_device *device = (disk_device *)cookie; mutex_lock(&gDeviceListLock); @@ -1096,7 +1096,8 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) case B_GET_MEDIA_STATUS: { *(status_t *)buffer = usb_disk_test_unit_ready(lun); - TRACE("B_GET_MEDIA_STATUS: 0x%08lx\n", *(status_t *)buffer); + TRACE("B_GET_MEDIA_STATUS: 0x%08" B_PRIx32 "\n", + *(status_t *)buffer); result = B_OK; break; } @@ -1117,8 +1118,9 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) geometry.removable = lun->removable; geometry.read_only = lun->write_protected; geometry.write_once = lun->device_type == B_WORM; - TRACE("B_GET_GEOMETRY: %ld sectors at %ld bytes per sector\n", - geometry.cylinder_count, geometry.bytes_per_sector); + TRACE("B_GET_GEOMETRY: %" B_PRId32 " sectors at %" B_PRId32 + " bytes per sector\n", geometry.cylinder_count, + geometry.bytes_per_sector); result = user_memcpy(buffer, &geometry, sizeof(device_geometry)); break; } @@ -1212,7 +1214,7 @@ usb_disk_read(void *cookie, off_t position, void *buffer, size_t *length) if (buffer == NULL || length == NULL) return B_BAD_VALUE; - TRACE("read(%lld, %ld)\n", position, *length); + TRACE("read(%" B_PRIdOFF ", %ld)\n", position, *length); device_lun *lun = (device_lun *)cookie; disk_device *device = lun->device; mutex_lock(&device->lock); @@ -1260,7 +1262,7 @@ usb_disk_write(void *cookie, off_t position, const void *buffer, if (buffer == NULL || length == NULL) return B_BAD_VALUE; - TRACE("write(%lld, %ld)\n", position, *length); + TRACE("write(%" B_PRIdOFF", %ld)\n", position, *length); device_lun *lun = (device_lun *)cookie; disk_device *device = lun->device; mutex_lock(&device->lock); From a20d64522658966dcfc148b5aeff24ad387fe768 Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Mon, 16 Sep 2013 13:27:42 +0200 Subject: [PATCH 083/137] usb_disk: fixed mounting a USB disk on x86_64 * usb_disk_prepare_partial_buffer() was miscalculating the offset in the temp buffer, which led to a page fault later when copying to the user buffer. --- src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp index d270798965..ff03f98071 100644 --- a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp @@ -963,7 +963,7 @@ usb_disk_prepare_partial_buffer(device_lun *lun, off_t position, size_t length, return result; } - off_t offset = position - (blockPosition * lun->block_size); + off_t offset = position - (off_t)blockPosition * lun->block_size; partialBuffer = (uint8 *)blockBuffer + offset; return B_OK; } From 1410faca6c30d39dc08a7bf7caa7630ce5a16d35 Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Mon, 16 Sep 2013 14:50:43 +0200 Subject: [PATCH 084/137] x86_64: added agp_gart, intel_gart, intel_extreme to the image. * tested on Intel GM45 and Atom_N4x0 --- build/jam/HaikuImage | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 84b2500786..7f3624bfbd 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -98,11 +98,11 @@ SYSTEM_NETWORK_PROTOCOLS = ipv4 tcp udp icmp unix icmp6 ipv6 ; SYSTEM_ADD_ONS_ACCELERANTS = [ FFilterByBuildFeatures x86,x86_64 @{ - vesa.accelerant + vesa.accelerant intel_extreme.accelerant }@ # x86,x86_64 x86 @{ 3dfx.accelerant ati.accelerant matrox.accelerant neomagic.accelerant - nvidia.accelerant intel_810.accelerant intel_extreme.accelerant + nvidia.accelerant intel_810.accelerant radeon.accelerant radeon_hd.accelerant s3.accelerant #via.accelerant vmware.accelerant }@ # x86 @@ -156,10 +156,10 @@ SYSTEM_ADD_ONS_DRIVERS_AUDIO = auich auvia echo3g emuxki hda ice1712 sis7018 ; SYSTEM_ADD_ONS_DRIVERS_AUDIO_OLD = ; #cmedia usb_audio ; SYSTEM_ADD_ONS_DRIVERS_GRAPHICS = [ FFilterByBuildFeatures x86,x86_64 @{ - vesa + vesa intel_extreme }@ # x86,x86_64 x86 @{ - ati 3dfx intel_810 intel_extreme matrox neomagic nvidia radeon radeon_hd + ati 3dfx intel_810 matrox neomagic nvidia radeon radeon_hd s3 #via vmware }@ # x86 ] ; @@ -187,7 +187,7 @@ SYSTEM_ADD_ONS_DRIVERS_NET = [ FFilterByBuildFeatures SYSTEM_ADD_ONS_DRIVERS_POWER = [ FFilterByBuildFeatures acpi_button@x86 ] ; SYSTEM_ADD_ONS_BUS_MANAGERS = [ FFilterByBuildFeatures ata@ata pci ps2@x86,x86_64 isa@x86,x86_64 - ide@ide scsi config_manager agp_gart@x86 usb firewire@x86 acpi@x86 + ide@ide scsi config_manager agp_gart@x86,x86_64 usb firewire@x86 acpi@x86 virtio random ] ; SYSTEM_ADD_ONS_FILE_SYSTEMS = bfs btrfs cdda exfat ext2 fat iso9660 nfs nfs4 @@ -216,7 +216,7 @@ for driver in $(SYSTEM_ADD_ONS_DRIVERS_NET) { AddFilesToHaikuImage system add-ons kernel bus_managers : $(SYSTEM_ADD_ONS_BUS_MANAGERS) ; AddFilesToHaikuImage system add-ons kernel busses agp_gart - : intel@x86 ; + : intel@x86,x86_64 ; if $(HAIKU_ATA_STACK) = 1 { AddFilesToHaikuImage system add-ons kernel busses ata From e968e4b09049ceef142d18f18a71b687813e7d66 Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Mon, 16 Sep 2013 15:05:28 +0200 Subject: [PATCH 085/137] intel_extreme: don't expose overlay in accelerant when not allocated ... in the driver. --- src/add-ons/accelerants/intel_extreme/accelerant.cpp | 8 +++++--- src/add-ons/accelerants/intel_extreme/mode.cpp | 5 ++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp b/src/add-ons/accelerants/intel_extreme/accelerant.cpp index 1ae8696859..7ef7269bd8 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp +++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp @@ -141,9 +141,11 @@ init_common(int device, bool isClone) // The overlay registers, hardware status, and cursor memory share // a single area with the shared_info - gInfo->overlay_registers = (struct overlay_registers*) - (gInfo->shared_info->graphics_memory - + gInfo->shared_info->overlay_offset); + if (gInfo->shared_info->overlay_offset != 0) { + gInfo->overlay_registers = (struct overlay_registers*) + (gInfo->shared_info->graphics_memory + + gInfo->shared_info->overlay_offset); + } if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_96x)) { // allocate some extra memory for the 3D context diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index 4e87f10f78..00182b8040 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -431,7 +431,10 @@ retrieve_current_mode(display_mode& mode, uint32 pllRegister) mode.h_display_start = 0; mode.v_display_start = 0; mode.flags = B_8_BIT_DAC | B_HARDWARE_CURSOR | B_PARALLEL_ACCESS - | B_DPMS | B_SUPPORTS_OVERLAYS; + | B_DPMS; + if (gInfo->overlay_registers != NULL) { + mode.flags |= B_SUPPORTS_OVERLAYS; + } } From b9b126139a57e5c239f935dc5cef11188042bdc8 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 16 Sep 2013 13:28:28 +0200 Subject: [PATCH 086/137] Debugger: add settings manager for source location mappings. - If it was necessary to help the debugger locate a particular source file due to it not being found on disk at the location specified in the debug information, the associated user-supplied path mappings are now saved and restored in the team settings. The file manager still needs a bit of extra work to apply these as files are added though. --- src/apps/debugger/Jamfile | 1 + .../debugger/controllers/TeamDebugger.cpp | 4 + src/apps/debugger/files/FileManager.cpp | 40 +++++- src/apps/debugger/files/FileManager.h | 9 ++ .../settings/TeamFileManagerSettings.cpp | 128 ++++++++++++++++++ .../settings/TeamFileManagerSettings.h | 41 ++++++ src/apps/debugger/settings/TeamSettings.cpp | 38 ++++++ src/apps/debugger/settings/TeamSettings.h | 9 ++ 8 files changed, 267 insertions(+), 3 deletions(-) create mode 100644 src/apps/debugger/settings/TeamFileManagerSettings.cpp create mode 100644 src/apps/debugger/settings/TeamFileManagerSettings.h diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index ac9212f809..1352fc5c36 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -181,6 +181,7 @@ Application Debugger : BreakpointSetting.cpp GuiTeamUiSettings.cpp SettingsManager.cpp + TeamFileManagerSettings.cpp TeamSettings.cpp TeamUiSettings.cpp TeamUiSettingsFactory.cpp diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp b/src/apps/debugger/controllers/TeamDebugger.cpp index b4a391b194..3226afa4b8 100644 --- a/src/apps/debugger/controllers/TeamDebugger.cpp +++ b/src/apps/debugger/controllers/TeamDebugger.cpp @@ -1991,6 +1991,8 @@ TeamDebugger::_LoadSettings() breakpointSetting->IsEnabled()); } + fFileManager->LoadLocationMappings(fTeamSettings.FileManagerSettings()); + const TeamUiSettings* uiSettings = fTeamSettings.UiSettingFor( fUserInterface->ID()); if (uiSettings != NULL) @@ -2022,6 +2024,8 @@ TeamDebugger::_SaveSettings() settings.AddUiSettings(clonedSettings); } } + + fFileManager->SaveLocationMappings(settings.FileManagerSettings()); locker.Unlock(); // save the settings diff --git a/src/apps/debugger/files/FileManager.cpp b/src/apps/debugger/files/FileManager.cpp index aaa78f27a2..36cd181aaf 100644 --- a/src/apps/debugger/files/FileManager.cpp +++ b/src/apps/debugger/files/FileManager.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011-2012, Rene Gollent, rene@gollent.com. + * Copyright 2011-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -15,6 +15,7 @@ #include "LocatableFile.h" #include "SourceFile.h" #include "StringUtils.h" +#include "TeamFileManagerSettings.h" // #pragma mark - EntryPath @@ -542,7 +543,8 @@ FileManager::FileManager() fLock("file manager"), fTargetDomain(NULL), fSourceDomain(NULL), - fSourceFiles(NULL) + fSourceFiles(NULL), + fLocationMappings() { } @@ -636,10 +638,18 @@ FileManager::GetSourceFile(const BString& path) void -FileManager::SourceEntryLocated(const BString& path, const BString& locatedPath) +FileManager::SourceEntryLocated(const BString& path, + const BString& locatedPath) { AutoLocker locker(this); fSourceDomain->EntryLocated(path, locatedPath); + + BMessage archivedMapping; + if (archivedMapping.AddString("source:path", path) == B_OK + && archivedMapping.AddString("source:locatedpath", locatedPath) + == B_OK) { + fLocationMappings.AddMessage("source:mapping", &archivedMapping); + } } @@ -687,6 +697,30 @@ FileManager::LoadSourceFile(LocatableFile* file, SourceFile*& _sourceFile) } +status_t +FileManager::LoadLocationMappings(TeamFileManagerSettings* settings) +{ + for (int32 i = 0; i < settings->CountSourceMappings(); i++) { + BString sourcePath; + BString locatedPath; + + if (settings->GetSourceMappingAt(i, sourcePath, locatedPath) != B_OK) + return B_NO_MEMORY; + + SourceEntryLocated(sourcePath, locatedPath); + } + + return B_OK; +} + + +status_t +FileManager::SaveLocationMappings(TeamFileManagerSettings* settings) +{ + return settings->SetTo(fLocationMappings); +} + + FileManager::SourceFileEntry* FileManager::_LookupSourceFile(const BString& path) { diff --git a/src/apps/debugger/files/FileManager.h b/src/apps/debugger/files/FileManager.h index 559942152b..24396124cb 100644 --- a/src/apps/debugger/files/FileManager.h +++ b/src/apps/debugger/files/FileManager.h @@ -1,11 +1,13 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef FILE_MANAGER_H #define FILE_MANAGER_H #include +#include #include #include @@ -15,6 +17,7 @@ class LocatableEntry; class LocatableFile; class SourceFile; +class TeamFileManagerSettings; class FileManager { @@ -47,6 +50,11 @@ public: SourceFile*& _sourceFile); // returns a reference + status_t LoadLocationMappings(TeamFileManagerSettings* + settings); + status_t SaveLocationMappings(TeamFileManagerSettings* + settings); + private: struct EntryPath; struct EntryHashDefinition; @@ -70,6 +78,7 @@ private: Domain* fTargetDomain; Domain* fSourceDomain; SourceFileTable* fSourceFiles; + BMessage fLocationMappings; }; diff --git a/src/apps/debugger/settings/TeamFileManagerSettings.cpp b/src/apps/debugger/settings/TeamFileManagerSettings.cpp new file mode 100644 index 0000000000..041b803ce1 --- /dev/null +++ b/src/apps/debugger/settings/TeamFileManagerSettings.cpp @@ -0,0 +1,128 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#include "TeamFileManagerSettings.h" + +TeamFileManagerSettings::TeamFileManagerSettings() + : + fValues() +{ +} + + +TeamFileManagerSettings::~TeamFileManagerSettings() +{ +} + + +TeamFileManagerSettings& +TeamFileManagerSettings::operator=(const TeamFileManagerSettings& other) +{ + fValues = other.fValues; + + return *this; +} + + +const char* +TeamFileManagerSettings::ID() const +{ + return "FileManager"; +} + + +status_t +TeamFileManagerSettings::SetTo(const BMessage& archive) +{ + try { + fValues = archive; + } catch (...) { + return B_NO_MEMORY; + } + + return B_OK; +} + + +status_t +TeamFileManagerSettings::WriteTo(BMessage& archive) const +{ + try { + archive = fValues; + } catch (...) { + return B_NO_MEMORY; + } + + return B_OK; +} + + +int32 +TeamFileManagerSettings::CountSourceMappings() const +{ + type_code type; + int32 count = 0; + + if (fValues.GetInfo("source:mapping", &type, &count) == B_OK) + return count; + + return 0; +} + + +status_t +TeamFileManagerSettings::AddSourceMapping(const BString& sourcePath, + const BString& locatedPath) +{ + BMessage mapping; + if (mapping.AddString("source:path", sourcePath) != B_OK + || mapping.AddString("source:locatedpath", locatedPath) != B_OK + || fValues.AddMessage("source:mapping", &mapping) != B_OK) { + return B_NO_MEMORY; + } + + return B_OK; +} + + +status_t +TeamFileManagerSettings::RemoveSourceMappingAt(int32 index) +{ + return fValues.RemoveData("mapping", index); +} + + +status_t +TeamFileManagerSettings::GetSourceMappingAt(int32 index, BString& sourcePath, + BString& locatedPath) +{ + BMessage mapping; + status_t error = fValues.FindMessage("mapping", index, &mapping); + if (error != B_OK) + return error; + + error = mapping.FindString("source:path", &sourcePath); + if (error != B_OK) + return error; + + return mapping.FindString("source:locatedpath", &locatedPath); +} + + +TeamFileManagerSettings* +TeamFileManagerSettings::Clone() const +{ + TeamFileManagerSettings* settings = new(std::nothrow) + TeamFileManagerSettings(); + + if (settings == NULL) + return NULL; + + if (settings->SetTo(fValues) != B_OK) { + delete settings; + return NULL; + } + + return settings; +} diff --git a/src/apps/debugger/settings/TeamFileManagerSettings.h b/src/apps/debugger/settings/TeamFileManagerSettings.h new file mode 100644 index 0000000000..5663ce3000 --- /dev/null +++ b/src/apps/debugger/settings/TeamFileManagerSettings.h @@ -0,0 +1,41 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef TEAM_FILE_MANAGER_SETTINGS_H +#define TEAM_FILE_MANAGER_SETTINGS_H + +#include + + +class TeamFileManagerSettings { +public: + TeamFileManagerSettings(); + virtual ~TeamFileManagerSettings(); + + TeamFileManagerSettings& + operator=( + const TeamFileManagerSettings& other); + // throws std::bad_alloc; + + const char* ID() const; + status_t SetTo(const BMessage& archive); + status_t WriteTo(BMessage& archive) const; + + int32 CountSourceMappings() const; + status_t AddSourceMapping(const BString& sourcePath, + const BString& locatedPath); + status_t RemoveSourceMappingAt(int32 index); + status_t GetSourceMappingAt(int32 index, + BString& sourcePath, BString& locatedPath); + + virtual TeamFileManagerSettings* + Clone() const; + // throws std::bad_alloc + +private: + BMessage fValues; +}; + + +#endif // TEAM_FILE_MANAGER_SETTINGS_H diff --git a/src/apps/debugger/settings/TeamSettings.cpp b/src/apps/debugger/settings/TeamSettings.cpp index cf3154151c..99c38a0be8 100644 --- a/src/apps/debugger/settings/TeamSettings.cpp +++ b/src/apps/debugger/settings/TeamSettings.cpp @@ -16,6 +16,7 @@ #include "ArchivingUtils.h" #include "BreakpointSetting.h" #include "Team.h" +#include "TeamFileManagerSettings.h" #include "TeamUiSettings.h" #include "TeamUiSettingsFactory.h" #include "UserBreakpoint.h" @@ -23,6 +24,7 @@ TeamSettings::TeamSettings() { + fFileManagerSettings = new TeamFileManagerSettings(); } @@ -115,6 +117,12 @@ TeamSettings::SetTo(const BMessage& archive) } } + if (archive.FindMessage("filemanagersettings", &childArchive) == B_OK) { + error = fFileManagerSettings->SetTo(childArchive); + if (error != B_OK) + return error; + } + return B_OK; } @@ -149,6 +157,14 @@ TeamSettings::WriteTo(BMessage& archive) const return error; } + error = fFileManagerSettings->WriteTo(childArchive); + if (error != B_OK) + return error; + + error = archive.AddMessage("filemanagersettings", &childArchive); + if (error != B_OK) + return error; + return B_OK; } @@ -234,10 +250,32 @@ TeamSettings::operator=(const TeamSettings& other) } } + *fFileManagerSettings = *other.fFileManagerSettings; + return *this; } +TeamFileManagerSettings* +TeamSettings::FileManagerSettings() const +{ + return fFileManagerSettings; +} + + +status_t +TeamSettings::SetFileManagerSettings(TeamFileManagerSettings* settings) +{ + try { + *fFileManagerSettings = *settings; + } catch (...) { + return B_NO_MEMORY; + } + + return B_OK; +} + + void TeamSettings::_Unset() { diff --git a/src/apps/debugger/settings/TeamSettings.h b/src/apps/debugger/settings/TeamSettings.h index f41f2bf8bd..6f71cda7ef 100644 --- a/src/apps/debugger/settings/TeamSettings.h +++ b/src/apps/debugger/settings/TeamSettings.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef TEAM_SETTINGS_H @@ -15,6 +16,7 @@ class BMessage; class Team; class BreakpointSetting; class TeamUiSettings; +class TeamFileManagerSettings; class TeamSettings { @@ -41,6 +43,11 @@ public: TeamSettings& operator=(const TeamSettings& other); // throws std::bad_alloc + TeamFileManagerSettings* + FileManagerSettings() const; + status_t SetFileManagerSettings( + TeamFileManagerSettings* settings); + private: typedef BObjectList BreakpointList; typedef BObjectList UiSettingsList; @@ -51,6 +58,8 @@ private: private: BreakpointList fBreakpoints; UiSettingsList fUiSettings; + TeamFileManagerSettings* + fFileManagerSettings; BString fTeamName; }; From 37fc9962f8ef8df69f2ad41ff0cdaa0f32fa8dda Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 16 Sep 2013 15:21:18 +0200 Subject: [PATCH 087/137] Fix incorrect name usage. --- src/apps/debugger/settings/TeamFileManagerSettings.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/debugger/settings/TeamFileManagerSettings.cpp b/src/apps/debugger/settings/TeamFileManagerSettings.cpp index 041b803ce1..dae7c79f0f 100644 --- a/src/apps/debugger/settings/TeamFileManagerSettings.cpp +++ b/src/apps/debugger/settings/TeamFileManagerSettings.cpp @@ -89,7 +89,7 @@ TeamFileManagerSettings::AddSourceMapping(const BString& sourcePath, status_t TeamFileManagerSettings::RemoveSourceMappingAt(int32 index) { - return fValues.RemoveData("mapping", index); + return fValues.RemoveData("source:mapping", index); } @@ -98,7 +98,7 @@ TeamFileManagerSettings::GetSourceMappingAt(int32 index, BString& sourcePath, BString& locatedPath) { BMessage mapping; - status_t error = fValues.FindMessage("mapping", index, &mapping); + status_t error = fValues.FindMessage("source:mapping", index, &mapping); if (error != B_OK) return error; From 29fdf5e8aed6e54ff039ffecf4abb8a77897b836 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 16 Sep 2013 15:22:05 +0200 Subject: [PATCH 088/137] Debugger: Implement #9961. - FileManager now saves any explicitly located file mappings, and properly restores them when reloading the same team/files later. --- src/apps/debugger/files/FileManager.cpp | 66 ++++++++++++++++++++----- src/apps/debugger/files/FileManager.h | 10 +++- 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/apps/debugger/files/FileManager.cpp b/src/apps/debugger/files/FileManager.cpp index 36cd181aaf..66fbe6391b 100644 --- a/src/apps/debugger/files/FileManager.cpp +++ b/src/apps/debugger/files/FileManager.cpp @@ -543,8 +543,7 @@ FileManager::FileManager() fLock("file manager"), fTargetDomain(NULL), fSourceDomain(NULL), - fSourceFiles(NULL), - fLocationMappings() + fSourceFiles(NULL) { } @@ -613,7 +612,8 @@ FileManager::GetTargetFile(const BString& path) void -FileManager::TargetEntryLocated(const BString& path, const BString& locatedPath) +FileManager::TargetEntryLocated(const BString& path, + const BString& locatedPath) { AutoLocker locker(this); fTargetDomain->EntryLocated(path, locatedPath); @@ -625,7 +625,14 @@ FileManager::GetSourceFile(const BString& directory, const BString& relativePath) { AutoLocker locker(this); - return fSourceDomain->GetFile(directory, relativePath); + LocatableFile* file = fSourceDomain->GetFile(directory, relativePath); + + if (directory.Length() == 0 || relativePath[0] == '/') + _LocateFileIfMapped(relativePath, file); + else + _LocateFileIfMapped(BString(directory) << '/' << relativePath, file); + + return file; } @@ -633,23 +640,27 @@ LocatableFile* FileManager::GetSourceFile(const BString& path) { AutoLocker locker(this); - return fSourceDomain->GetFile(path); + LocatableFile* file = fSourceDomain->GetFile(path); + _LocateFileIfMapped(path, file); + + return file; } -void +status_t FileManager::SourceEntryLocated(const BString& path, const BString& locatedPath) { AutoLocker locker(this); fSourceDomain->EntryLocated(path, locatedPath); - BMessage archivedMapping; - if (archivedMapping.AddString("source:path", path) == B_OK - && archivedMapping.AddString("source:locatedpath", locatedPath) - == B_OK) { - fLocationMappings.AddMessage("source:mapping", &archivedMapping); + try { + fSourceLocationMappings[path] = locatedPath; + } catch (...) { + return B_NO_MEMORY; } + + return B_OK; } @@ -700,6 +711,8 @@ FileManager::LoadSourceFile(LocatableFile* file, SourceFile*& _sourceFile) status_t FileManager::LoadLocationMappings(TeamFileManagerSettings* settings) { + AutoLocker locker(this); + for (int32 i = 0; i < settings->CountSourceMappings(); i++) { BString sourcePath; BString locatedPath; @@ -707,7 +720,11 @@ FileManager::LoadLocationMappings(TeamFileManagerSettings* settings) if (settings->GetSourceMappingAt(i, sourcePath, locatedPath) != B_OK) return B_NO_MEMORY; - SourceEntryLocated(sourcePath, locatedPath); + try { + fSourceLocationMappings[sourcePath] = locatedPath; + } catch (...) { + return B_NO_MEMORY; + } } return B_OK; @@ -717,7 +734,16 @@ FileManager::LoadLocationMappings(TeamFileManagerSettings* settings) status_t FileManager::SaveLocationMappings(TeamFileManagerSettings* settings) { - return settings->SetTo(fLocationMappings); + AutoLocker locker(this); + + for (LocatedFileMap::const_iterator it = fSourceLocationMappings.begin(); + it != fSourceLocationMappings.end(); ++it) { + status_t error = settings->AddSourceMapping(it->first, it->second); + if (error != B_OK) + return error; + } + + return B_OK; } @@ -747,3 +773,17 @@ FileManager::_SourceFileUnused(SourceFileEntry* entry) if (otherEntry == entry) fSourceFiles->Remove(entry); } + + +void +FileManager::_LocateFileIfMapped(const BString& sourcePath, + LocatableFile* file) +{ + // called with lock held + LocatedFileMap::const_iterator it = fSourceLocationMappings.find( + sourcePath); + if (it != fSourceLocationMappings.end() + && file->State() != LOCATABLE_ENTRY_LOCATED_EXPLICITLY) { + fSourceDomain->EntryLocated(it->first, it->second); + } +} diff --git a/src/apps/debugger/files/FileManager.h b/src/apps/debugger/files/FileManager.h index 24396124cb..e008fa5b4b 100644 --- a/src/apps/debugger/files/FileManager.h +++ b/src/apps/debugger/files/FileManager.h @@ -6,6 +6,8 @@ #ifndef FILE_MANAGER_H #define FILE_MANAGER_H +#include + #include #include #include @@ -43,7 +45,7 @@ public: // returns a reference LocatableFile* GetSourceFile(const BString& path); // returns a reference - void SourceEntryLocated(const BString& path, + status_t SourceEntryLocated(const BString& path, const BString& locatedPath); status_t LoadSourceFile(LocatableFile* file, @@ -65,6 +67,7 @@ private: typedef BOpenHashTable LocatableEntryTable; typedef DoublyLinkedList DeadEntryList; typedef BOpenHashTable SourceFileTable; + typedef std::map LocatedFileMap; friend struct SourceFileEntry; // for gcc 2 @@ -72,13 +75,16 @@ private: private: SourceFileEntry* _LookupSourceFile(const BString& path); void _SourceFileUnused(SourceFileEntry* entry); + void _LocateFileIfMapped(const BString& sourcePath, + LocatableFile* file); private: BLocker fLock; Domain* fTargetDomain; Domain* fSourceDomain; SourceFileTable* fSourceFiles; - BMessage fLocationMappings; + + LocatedFileMap fSourceLocationMappings; }; From 6c5893fbbf22dfc58f622c244ee09a718f89ad43 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 16 Sep 2013 19:45:27 +0200 Subject: [PATCH 089/137] Debugger: Add selection support to MemoryView. - The Inspector's memory view now supports selecting chunks of the hex display in the manner one would in a TextView. The selection can also be copied to the clipboard, or if it matches the size of a target address, can be used as input for an address to inspect directly. Still needs some fine tuning, but basically works. --- .../gui/inspector_window/MemoryView.cpp | 443 ++++++++++++++++-- .../gui/inspector_window/MemoryView.h | 34 +- 2 files changed, 442 insertions(+), 35 deletions(-) diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp index a59e96760e..c00e38a1b2 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp +++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp @@ -11,20 +11,30 @@ #include #include +#include #include +#include +#include #include +#include +#include #include #include #include "Architecture.h" +#include "AutoDeleter.h" +#include "MessageCodes.h" #include "Team.h" #include "TeamMemoryBlock.h" enum { - MSG_TARGET_ADDRESS_CHANGED = 'mtac' + MSG_TARGET_ADDRESS_CHANGED = 'mtac', + MSG_VIEW_AUTOSCROLL = 'mvas' }; +static const bigtime_t kScrollTimer = 10000LL; + MemoryView::MemoryView(::Team* team, Listener* listener) : @@ -39,6 +49,10 @@ MemoryView::MemoryView(::Team* team, Listener* listener) fHexBlocksPerLine(0), fHexMode(HexMode8BitInt), fTextMode(TextModeASCII), + fSelectionBase(0), + fSelectionStart(0), + fSelectionEnd(0), + fScrollRunner(NULL), fListener(listener) { Architecture* architecture = team->GetArchitecture(); @@ -76,11 +90,14 @@ void MemoryView::SetTargetAddress(TeamMemoryBlock* block, target_addr_t address) { fTargetAddress = address; - if (fTargetBlock != NULL) + if (block != fTargetBlock && fTargetBlock != NULL) fTargetBlock->ReleaseReference(); - fTargetBlock = block; - fTargetBlock->AcquireReference(); + if (block != fTargetBlock) { + fTargetBlock = block; + fTargetBlock->AcquireReference(); + } + MakeFocus(true); BMessenger(this).SendMessage(MSG_TARGET_ADDRESS_CHANGED); } @@ -119,7 +136,7 @@ MemoryView::Draw(BRect rect) if (fTargetBlock == NULL) return; - uint32 hexBlockSize = (1 << fHexMode) + 1; + uint32 hexBlockSize = _GetHexDigitsPerBlock() + 1; uint32 blockByteSize = hexBlockSize / 2; if (fHexMode != HexModeNone && fTextMode != TextModeNone) { divider += (fHexBlocksPerLine * hexBlockSize + 1) * fCharWidth; @@ -156,7 +173,6 @@ MemoryView::Draw(BRect rect) DrawString(buffer, drawPoint); drawPoint.x += fCharWidth * (fTargetAddressSize + 2); PopState(); - if (fHexMode != HexModeNone) { if (currentAddress + (currentBlocksPerLine * blockByteSize) > maxAddress) { @@ -190,6 +206,7 @@ MemoryView::Draw(BRect rect) drawPoint.x += fCharWidth * hexBlockSize * (fHexBlocksPerLine - currentBlocksPerLine); } + if (fTextMode != TextModeNone) { drawPoint.x += fCharWidth; for (int32 j = 0; j < currentCharsPerLine; j++) { @@ -226,6 +243,15 @@ MemoryView::Draw(BRect rect) lineAddress += fTextCharsPerLine; } } + + if (fSelectionStart != fSelectionEnd) { + PushState(); + BRegion selectionRegion; + _GetSelectionRegion(selectionRegion); + SetDrawingMode(B_OP_INVERT); + FillRegion(&selectionRegion, B_SOLID_HIGH); + PopState(); + } } @@ -332,6 +358,11 @@ void MemoryView::MessageReceived(BMessage* message) { switch(message->what) { + case B_COPY: + { + _CopySelectionToClipboard(); + break; + } case MSG_TARGET_ADDRESS_CHANGED: { _RecalcScrollBars(); @@ -370,6 +401,11 @@ MemoryView::MessageReceived(BMessage* message) } break; } + case MSG_VIEW_AUTOSCROLL: + { + _HandleAutoScroll(); + break; + } default: { BView::MessageReceived(message); @@ -385,7 +421,78 @@ MemoryView::MouseDown(BPoint point) if (!IsFocus()) MakeFocus(true); - BView::MouseDown(point); + if (fTargetBlock == NULL) + return; + + int32 buttons; + if (Looper()->CurrentMessage()->FindInt32("buttons", &buttons) != B_OK) + buttons = B_PRIMARY_MOUSE_BUTTON; + + if (buttons == B_SECONDARY_MOUSE_BUTTON) { + _HandleContextMenu(point); + return; + } + + int32 offset = _GetOffsetAt(point); + if (offset < fSelectionStart || offset > fSelectionEnd) { + BRegion oldSelectionRegion; + _GetSelectionRegion(oldSelectionRegion); + fSelectionBase = offset; + fSelectionStart = fSelectionBase; + fSelectionEnd = fSelectionBase; + Invalidate(oldSelectionRegion.Frame()); + } + + SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); + fTrackingMouse = true; +} + + +void +MemoryView::MouseMoved(BPoint point, uint32 transit, const BMessage* message) +{ + if (!fTrackingMouse) + return; + + BRegion oldSelectionRegion; + _GetSelectionRegion(oldSelectionRegion); + int32 offset = _GetOffsetAt(point); + if (offset < fSelectionBase) { + fSelectionStart = offset; + fSelectionEnd = fSelectionBase; + } else { + fSelectionStart = fSelectionBase; + fSelectionEnd = offset; + } + + BRegion region; + _GetSelectionRegion(region); + region.Include(&oldSelectionRegion); + Invalidate(region.Frame()); + + switch (transit) { + case B_EXITED_VIEW: + fScrollRunner = new BMessageRunner(BMessenger(this), + new BMessage(MSG_VIEW_AUTOSCROLL), kScrollTimer); + break; + + case B_ENTERED_VIEW: + delete fScrollRunner; + fScrollRunner = NULL; + break; + + default: + break; + } +} + + +void +MemoryView::MouseUp(BPoint point) +{ + fTrackingMouse = false; + delete fScrollRunner; + fScrollRunner = NULL; } @@ -395,10 +502,12 @@ MemoryView::ScrollToSelection() if (fTargetBlock != NULL) { target_addr_t offset = fTargetAddress - fTargetBlock->BaseAddress(); int32 lineNumber = 0; - if (fHexBlocksPerLine > 0) - lineNumber = offset / (fHexBlocksPerLine * (1 << (fHexMode - 1))); - else if (fTextCharsPerLine > 0) + if (fHexBlocksPerLine > 0) { + lineNumber = offset / (fHexBlocksPerLine + * (_GetHexDigitsPerBlock() / 2)); + } else if (fTextCharsPerLine > 0) lineNumber = offset / fTextCharsPerLine; + float y = lineNumber * fLineHeight; if (y < Bounds().top) ScrollTo(0.0, y); @@ -429,40 +538,23 @@ MemoryView::_RecalcScrollBars() float max = 0.0; BScrollBar *scrollBar = ScrollBar(B_VERTICAL); if (fTargetBlock != NULL) { - BRect bounds = Bounds(); - // the left portion of the view is off limits since it - // houses the address offset of the current line - float baseWidth = bounds.Width() - ((fTargetAddressSize + 2) - * fCharWidth); - float hexWidth = 0.0; - float textWidth = 0.0; - int32 hexDigits = 1 << fHexMode; + int32 hexDigits = _GetHexDigitsPerBlock(); int32 sizeFactor = 1 + hexDigits; - if (fHexMode != HexModeNone) { - if (fTextMode != TextModeNone) { - float hexProportion = sizeFactor / (float)(sizeFactor - + hexDigits / 2); - hexWidth = baseWidth * hexProportion; - // when sharing the display between hex and text, - // we allocate a 2 character space to separate the views - hexWidth -= 2 * fCharWidth; - textWidth = baseWidth - hexWidth; - } else - hexWidth = baseWidth; - } else if (fTextMode != TextModeNone) - textWidth = baseWidth; + _RecalcBounds(); + float hexWidth = fHexRight - fHexLeft; int32 nybblesPerLine = int32(hexWidth / fCharWidth); fHexBlocksPerLine = 0; fTextCharsPerLine = 0; if (fHexMode != HexModeNone) { fHexBlocksPerLine = nybblesPerLine / sizeFactor; fHexBlocksPerLine &= ~1; + fHexRight = fHexLeft + (fHexBlocksPerLine * sizeFactor + * fCharWidth); if (fTextMode != TextModeNone) fTextCharsPerLine = fHexBlocksPerLine * hexDigits / 2; } else if (fTextMode != TextModeNone) - fTextCharsPerLine = int32(textWidth / fCharWidth); - + fTextCharsPerLine = int32((fTextRight - fTextLeft) / fCharWidth); int32 lineCount = 0; float totalHeight = 0.0; if (fHexBlocksPerLine > 0) { @@ -473,6 +565,7 @@ MemoryView::_RecalcScrollBars() totalHeight = lineCount * fLineHeight; if (totalHeight > 0.0) { + BRect bounds = Bounds(); max = totalHeight - bounds.Height(); scrollBar->SetProportion(bounds.Height() / totalHeight); scrollBar->SetSteps(fLineHeight, bounds.Height()); @@ -558,6 +651,290 @@ MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize, } +int32 +MemoryView::_GetOffsetAt(BPoint point) const +{ + if (fTargetBlock == NULL) + return -1; + + // TODO: support selection in the text region as well + if (fHexMode == HexModeNone) + return -1; + + int32 lineNumber = point.y / fLineHeight; + int32 charsPerBlock = _GetHexDigitsPerBlock() / 2; + int32 totalHexBlocks = fTargetBlock->Size() / charsPerBlock; + int32 lineCount = totalHexBlocks / fHexBlocksPerLine; + + if (lineNumber >= lineCount) + return -1; + + point.x -= fHexLeft; + if (point.x < 0) + point.x = 0; + else if (point.x > fHexRight) + point.x = fHexRight; + + float blockWidth = (charsPerBlock * 2 + 1) * fCharWidth; + int32 containingBlock = int32(floor(point.x / blockWidth)); + + return fHexBlocksPerLine * lineNumber + + containingBlock * charsPerBlock; +} + + +BPoint +MemoryView::_GetPointForOffset(int32 offset) const +{ + BPoint point; + int32 bytesPerLine = fHexBlocksPerLine * _GetHexDigitsPerBlock() / 2; + int32 line = offset / bytesPerLine; + int32 lineOffset = offset % bytesPerLine; + + point.x = fHexLeft + (lineOffset * 2 * fCharWidth) + + (lineOffset * 2 * fCharWidth / _GetHexDigitsPerBlock()); + point.y = line * fLineHeight; + + return point; +} + + +void +MemoryView::_RecalcBounds() +{ + fHexLeft = 0; + fHexRight = 0; + fTextLeft = 0; + fTextRight = 0; + + // the left bound is determined by the space taken up by the actual + // displayed addresses. + float left = _GetAddressDisplayWidth(); + float width = Bounds().Width() - left; + + if (fHexMode != HexModeNone) { + int32 hexDigits = _GetHexDigitsPerBlock(); + int32 sizeFactor = 1 + hexDigits; + if (fTextMode != TextModeNone) { + float hexProportion = sizeFactor / (float)(sizeFactor + + hexDigits / 2); + float hexWidth = width * hexProportion; + fTextLeft = left + hexWidth; + fHexLeft = left; + // when sharing the display between hex and text, + // we allocate a 2 character space to separate the views + hexWidth -= 2 * fCharWidth; + fHexRight = left + hexWidth; + } else { + fHexLeft = left; + fHexRight = left + width; + } + } else if (fTextMode != TextModeNone) { + fTextLeft = left; + fTextRight = left + width; + } +} + + +float +MemoryView::_GetAddressDisplayWidth() const +{ + return (fTargetAddressSize + 2) * fCharWidth; +} + + +void +MemoryView::_GetSelectionRegion(BRegion& region) +{ + region.MakeEmpty(); + BPoint startPoint = _GetPointForOffset(fSelectionStart); + BPoint endPoint = _GetPointForOffset(fSelectionEnd); + + BRect rect; + if (startPoint.y == endPoint.y) { + // single line case + rect.left = startPoint.x; + rect.top = startPoint.y; + rect.right = endPoint.x; + rect.bottom = endPoint.y + fLineHeight; + region.Include(rect); + } else { + float currentLine = startPoint.y; + + // first line + rect.left = startPoint.x; + rect.top = startPoint.y; + rect.right = fHexRight; + rect.bottom = startPoint.y + fLineHeight; + region.Include(rect); + currentLine += fLineHeight; + + // middle region + if (currentLine < endPoint.y) { + rect.left = fHexLeft; + rect.top = currentLine; + rect.right = fHexRight; + rect.bottom = endPoint.y; + region.Include(rect); + } + + rect.left = fHexLeft; + rect.top = endPoint.y; + rect.right = endPoint.x; + rect.bottom = endPoint.y + fLineHeight; + region.Include(rect); + } +} + + +void +MemoryView::_GetSelectedText(BString& text) +{ + if (fSelectionStart == fSelectionEnd) + return; + + text.Truncate(0); + + char* data = (char *)fTargetBlock->Data() + fSelectionStart; + int16 blockSize = _GetHexDigitsPerBlock() / 2; + int32 count = (fSelectionEnd - fSelectionStart) + / blockSize; + + char buffer[32]; + for (int32 i = 0; i < count; i++) { + _GetNextHexBlock(buffer, sizeof(buffer), data); + data += blockSize; + text << buffer; + if (i < count - 1) + text << " "; + } +} + + +void +MemoryView::_CopySelectionToClipboard() +{ + BString text; + _GetSelectedText(text); + + if (text.Length() > 0) { + be_clipboard->Lock(); + be_clipboard->Data()->RemoveData("text/plain"); + be_clipboard->Data()->AddData ("text/plain", + B_MIME_TYPE, text.String(), text.Length()); + be_clipboard->Commit(); + be_clipboard->Unlock(); + } +} + + +void +MemoryView::_HandleAutoScroll() +{ + BPoint point; + uint32 buttons; + GetMouse(&point, &buttons); + float difference = 0.0; + int factor = 0; + BRect visibleRect = Bounds(); + if (point.y < visibleRect.top) + difference = point.y - visibleRect.top; + else if (point.y > visibleRect.bottom) + difference = point.y - visibleRect.bottom; + if (difference != 0.0) { + factor = (int)(ceilf(difference / fLineHeight)); + _ScrollByLines(factor); + } + + MouseMoved(point, B_OUTSIDE_VIEW, NULL); +} + + +void +MemoryView::_ScrollByLines(int32 lineCount) +{ + BScrollBar* vertical = ScrollBar(B_VERTICAL); + if (vertical == NULL) + return; + + float value = vertical->Value(); + vertical->SetValue(value + fLineHeight * lineCount); +} + + +void +MemoryView::_HandleContextMenu(BPoint point) +{ + int32 offset = _GetOffsetAt(point); + if (offset < fSelectionStart || offset > fSelectionEnd) + return; + + BPopUpMenu* menu = new(std::nothrow) BPopUpMenu("Options"); + if (menu == NULL) + return; + + ObjectDeleter menuDeleter(menu); + ObjectDeleter itemDeleter; + ObjectDeleter messageDeleter; + BMessage* message = NULL; + BMenuItem* item = NULL; + if (fSelectionEnd - fSelectionStart == fTargetAddressSize / 2) { + BMessage* message = new(std::nothrow) BMessage(MSG_INSPECT_ADDRESS); + if (message == NULL) + return; + + target_addr_t address; + if (fTargetAddressSize == 8) + address = *((uint32*)(fTargetBlock->Data() + fSelectionStart)); + else + address = *((uint64*)(fTargetBlock->Data() + fSelectionStart)); + + if (fEndianMode == EndianModeBigEndian) + address = B_HOST_TO_BENDIAN_INT64(address); + else + address = B_HOST_TO_LENDIAN_INT64(address); + + messageDeleter.SetTo(message); + message->AddUInt64("address", address); + BMenuItem* item = new(std::nothrow) BMenuItem("Inspect", message); + if (item == NULL) + return; + + messageDeleter.Detach(); + itemDeleter.SetTo(item); + if (!menu->AddItem(item)) + return; + + item->SetTarget(Looper()); + itemDeleter.Detach(); + } + + message = new(std::nothrow) BMessage(B_COPY); + if (message == NULL) + return; + + messageDeleter.SetTo(message); + item = new(std::nothrow) BMenuItem("Copy", message); + if (item == NULL) + return; + + messageDeleter.Detach(); + itemDeleter.SetTo(item); + if (!menu->AddItem(item)) + return; + + item->SetTarget(this); + itemDeleter.Detach(); + menuDeleter.Detach(); + + BPoint screenWhere(point); + ConvertToScreen(&screenWhere); + BRect mouseRect(screenWhere, screenWhere); + mouseRect.InsetBy(-4.0, -4.0); + menu->Go(screenWhere, true, false, mouseRect, true); +} + + //#pragma mark - Listener diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h index ca10a25c48..9731971432 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h +++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.h @@ -38,9 +38,9 @@ enum { }; +class BMessageRunner; + class Team; - - class TeamMemoryBlock; @@ -66,6 +66,9 @@ public: virtual void MakeFocus(bool isFocused); virtual void MessageReceived(BMessage* message); virtual void MouseDown(BPoint point); + virtual void MouseMoved(BPoint point, uint32 transit, + const BMessage* dragMessage); + virtual void MouseUp(BPoint point); void ScrollToSelection(); virtual void TargetedByScrollView(BScrollView* scrollView); @@ -75,6 +78,22 @@ private: void _GetNextHexBlock(char* buffer, int32 bufferSize, const char* address); + int32 _GetOffsetAt(BPoint point) const; + BPoint _GetPointForOffset(int32 offset) const; + void _RecalcBounds(); + float _GetAddressDisplayWidth() const; + + inline int32 _GetHexDigitsPerBlock() const + { return 1 << fHexMode; }; + + void _GetSelectionRegion(BRegion& region); + void _GetSelectedText(BString& text); + void _CopySelectionToClipboard(); + + void _HandleAutoScroll(); + void _ScrollByLines(int32 lineCount); + void _HandleContextMenu(BPoint point); + private: ::Team* fTeam; TeamMemoryBlock* fTargetBlock; @@ -87,6 +106,17 @@ private: int32 fCurrentEndianMode; int32 fHexMode; int32 fTextMode; + float fHexLeft; + float fHexRight; + float fTextLeft; + float fTextRight; + int32 fSelectionBase; + int32 fSelectionStart; + int32 fSelectionEnd; + BMessageRunner* fScrollRunner; + + bool fTrackingMouse; + Listener* fListener; }; From af967edb7d20fe472ac7dc2c013e13fcbc249ca3 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 16 Sep 2013 19:59:33 +0200 Subject: [PATCH 090/137] Build fix. --- .../debugger/user_interface/gui/inspector_window/MemoryView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp index c00e38a1b2..4c945d01ea 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp +++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp @@ -889,7 +889,7 @@ MemoryView::_HandleContextMenu(BPoint point) else address = *((uint64*)(fTargetBlock->Data() + fSelectionStart)); - if (fEndianMode == EndianModeBigEndian) + if (fCurrentEndianMode == EndianModeBigEndian) address = B_HOST_TO_BENDIAN_INT64(address); else address = B_HOST_TO_LENDIAN_INT64(address); From fb916bc870d42cb7980c244b337edcda4be82c36 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 16 Sep 2013 20:22:24 +0200 Subject: [PATCH 091/137] Debugger: Fix data copy issue. - B_PRIx8 unfortunately doesn't necessarily strictly stay within the bounds of an 8-bit hex constant, so force the size passed to snprintf to make it that way. --- .../user_interface/gui/inspector_window/MemoryView.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp index 4c945d01ea..4f2979d951 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp +++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp @@ -802,7 +802,8 @@ MemoryView::_GetSelectedText(BString& text) char buffer[32]; for (int32 i = 0; i < count; i++) { - _GetNextHexBlock(buffer, sizeof(buffer), data); + _GetNextHexBlock(buffer, std::min(_GetHexDigitsPerBlock() + 1, + (int32)32), data); data += blockSize; text << buffer; if (i < count - 1) From f8319398742377547348d9664992553c297e9e21 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 16 Sep 2013 21:28:19 +0200 Subject: [PATCH 092/137] Fix previous format problem more correctly. Thanks Ingo, Oliver and Ithamar for the hint. --- .../user_interface/gui/inspector_window/MemoryView.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp index 4f2979d951..9a3947c7cf 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp +++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp @@ -184,9 +184,7 @@ MemoryView::Draw(BRect rect) for (int32 j = 0; j < currentBlocksPerLine; j++) { const char* blockAddress = currentAddress + (j * blockByteSize); - _GetNextHexBlock(buffer, - std::min((size_t)hexBlockSize, sizeof(buffer)), - blockAddress); + _GetNextHexBlock(buffer, sizeof(buffer), blockAddress); DrawString(buffer, drawPoint); if (targetAddress >= blockAddress && targetAddress < blockAddress + blockByteSize) { @@ -581,7 +579,8 @@ MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize, switch(fHexMode) { case HexMode8BitInt: { - snprintf(buffer, bufferSize, "%02" B_PRIx8, *address); + snprintf(buffer, bufferSize, "%02" B_PRIx8, + *((const uint8*)address)); break; } case HexMode16BitInt: @@ -802,8 +801,7 @@ MemoryView::_GetSelectedText(BString& text) char buffer[32]; for (int32 i = 0; i < count; i++) { - _GetNextHexBlock(buffer, std::min(_GetHexDigitsPerBlock() + 1, - (int32)32), data); + _GetNextHexBlock(buffer, sizeof(buffer), data); data += blockSize; text << buffer; if (i < count - 1) From 5f827428583095b828eadce5e7e13cb204f0b9ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 16 Sep 2013 22:07:43 +0200 Subject: [PATCH 093/137] HaikuDepot: Package information can be retrieved asynchronously --- src/apps/haiku-depot/MainWindow.cpp | 59 ++---------- src/apps/haiku-depot/Model.cpp | 84 +++++++++++++++++ src/apps/haiku-depot/Model.h | 10 ++ src/apps/haiku-depot/PackageInfoView.cpp | 113 ++++++++++++++++++++++- src/apps/haiku-depot/PackageInfoView.h | 14 ++- 5 files changed, 225 insertions(+), 55 deletions(-) diff --git a/src/apps/haiku-depot/MainWindow.cpp b/src/apps/haiku-depot/MainWindow.cpp index 92eaa9c338..6b332b93aa 100644 --- a/src/apps/haiku-depot/MainWindow.cpp +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -40,7 +40,7 @@ MainWindow::MainWindow(BRect frame) fFilterView = new FilterView(fModel); fPackageListView = new PackageListView(); - fPackageInfoView = new PackageInfoView(&fPackageManager); + fPackageInfoView = new PackageInfoView(fModel.Lock(), &fPackageManager); fSplitView = new BSplitView(B_VERTICAL, 5.0f); @@ -162,7 +162,8 @@ MainWindow::_AdoptModel() void MainWindow::_AdoptPackage(const PackageInfoRef& package) { - fPackageInfoView->SetPackage(*package.Get()); + fPackageInfoView->SetPackage(package); + fModel.PopulatePackage(package); } @@ -176,9 +177,12 @@ MainWindow::_ClearPackage() void MainWindow::_InitDummyModel() { - // TODO: The Model could be filled from another thread by - // sending messages which contain collected package information. - // The Model could be cached on disk. + // TODO: The Model needs to be filled initially by the Package Kit APIs. + // It already caches information locally. Error handlers need to be + // installed to display problems to the user. When a package is selected + // for display, extra information is retrieved like screen-shots, user- + // ratings and so on. This triggers notifications which in turn updates + // the UI. DepotInfo depot(B_TRANSLATE("Default")); @@ -197,16 +201,6 @@ MainWindow::_InitDummyModel() "on Haiku. It combines many great under-the-hood features with " "powerful tools and an efficient and intuitive interface.", "2.1.2 - Initial Haiku release."), true); - wonderbrush->AddUserRating( - UserRating(UserInfo("humdinger"), 4.5f, - "Awesome!", "en", "2.1.2", 0, 0) - ); - wonderbrush->AddUserRating( - UserRating(UserInfo("bonefish"), 5.0f, - "The best!", "en", "2.1.2", 3, 1) - ); - wonderbrush->AddScreenshot( - BitmapRef(new SharedBitmap(603), true)); wonderbrush->AddCategory(fModel.CategoryGraphics()); wonderbrush->AddCategory(fModel.CategoryProductivity()); @@ -228,23 +222,6 @@ MainWindow::_InitDummyModel() "missing from BeIDE, like running a project in the Terminal, " "and has a bundled text editor based upon Pe.", ""), true); - paladin->AddUserRating( - UserRating(UserInfo("stippi"), 3.5f, - "Could be more integrated from the sounds of it.", - "en", "1.2.0", 0, 1) - ); - paladin->AddUserRating( - UserRating(UserInfo("mmadia"), 5.0f, - "It rocks! Give a try", - "en", "1.1.0", 1, 0) - ); - paladin->AddUserRating( - UserRating(UserInfo("bonefish"), 2.0f, - "It just needs to use my jam-rewrite 'ham' and it will be great.", - "en", "1.1.0", 3, 1) - ); - paladin->AddScreenshot( - BitmapRef(new SharedBitmap(605), true)); paladin->AddCategory(fModel.CategoryDevelopment()); depot.AddPackage(paladin); @@ -315,24 +292,6 @@ MainWindow::_InitDummyModel() "filter.\n\n" " * ''Note to filter developers:'' The filter API has changed. You " "will need to recompile your filters."), true); - sequitur->AddUserRating( - UserRating(UserInfo("pete"), 4.5f, - "I can weave a web of sound! And it connects to PatchBay. Check " - "it out, I can wholeheartly recommend this app!! This rating " - "comment is of course only so long, because the new TextView " - "layout needs some testing. Oh, and did I mention it works with " - "custom installed sound fonts? Reading through this comment I find " - "that I did not until now. Hopefully there are enough lines now to " - "please the programmer with the text layouting and scrolling of " - "long ratings!", "en", "2.1.0", 4, 1) - ); - sequitur->AddUserRating( - UserRating(UserInfo("stippi"), 3.5f, - "It seems very capable. Still runs fine on Haiku. The interface " - "is composed of many small, hard to click items. But you can " - "configure a tool for each mouse button, which is great for the " - "work flow.", "en", "2.1.0", 2, 1) - ); sequitur->AddCategory(fModel.CategoryAudio()); depot.AddPackage(sequitur); diff --git a/src/apps/haiku-depot/Model.cpp b/src/apps/haiku-depot/Model.cpp index a6c16f5917..fecc10f5f4 100644 --- a/src/apps/haiku-depot/Model.cpp +++ b/src/apps/haiku-depot/Model.cpp @@ -7,6 +7,7 @@ #include +#include #include @@ -366,3 +367,86 @@ Model::SetSearchTerms(const BString& searchTerms) fSearchTermsFilter.SetTo(filter, true); } + +// #pragma mark - information retrival + + +void +Model::PopulatePackage(const PackageInfoRef& package) +{ + if (fPopulatedPackages.Contains(package)) + return; + + BAutolock _(&fLock); + + // TODO: Replace with actual backend that retrieves package extra + // information and user-contributed package information. + + // TODO: There should probably also be a way to "unpopulate" the + // package information. Maybe a cache of populated packages, so that + // packages loose their extra information after a certain amount of + // time when they have not been accessed/displayed in the UI. Otherwise + // HaikuDepot will consume more and more resources in the packages. + // Especially screen-shots will be a problem eventually. + + // TODO: Simulate a delay in retrieving this info, and do that on + // a separate thread. + + fPopulatedPackages.Add(package); + + if (package->Title() == "WonderBrush") { + + package->AddUserRating( + UserRating(UserInfo("humdinger"), 4.5f, + "Awesome!", "en", "2.1.2", 0, 0) + ); + package->AddUserRating( + UserRating(UserInfo("bonefish"), 5.0f, + "The best!", "en", "2.1.2", 3, 1) + ); + package->AddScreenshot( + BitmapRef(new SharedBitmap(603), true)); + + } else if (package->Title() == "Paladin") { + + package->AddUserRating( + UserRating(UserInfo("stippi"), 3.5f, + "Could be more integrated from the sounds of it.", + "en", "1.2.0", 0, 1) + ); + package->AddUserRating( + UserRating(UserInfo("mmadia"), 5.0f, + "It rocks! Give a try", + "en", "1.1.0", 1, 0) + ); + package->AddUserRating( + UserRating(UserInfo("bonefish"), 2.0f, + "It just needs to use my jam-rewrite 'ham' and it will be great.", + "en", "1.1.0", 3, 1) + ); + package->AddScreenshot( + BitmapRef(new SharedBitmap(605), true)); + + } else if (package->Title() == "Sequitur") { + + package->AddUserRating( + UserRating(UserInfo("pete"), 4.5f, + "I can weave a web of sound! And it connects to PatchBay. Check " + "it out, I can wholeheartly recommend this app!! This rating " + "comment is of course only so long, because the new TextView " + "layout needs some testing. Oh, and did I mention it works with " + "custom installed sound fonts? Reading through this comment I find " + "that I did not until now. Hopefully there are enough lines now to " + "please the programmer with the text layouting and scrolling of " + "long ratings!", "en", "2.1.0", 4, 1) + ); + package->AddUserRating( + UserRating(UserInfo("stippi"), 3.5f, + "It seems very capable. Still runs fine on Haiku. The interface " + "is composed of many small, hard to click items. But you can " + "configure a tool for each mouse button, which is great for the " + "work flow.", "en", "2.1.0", 2, 1) + ); + + } +} diff --git a/src/apps/haiku-depot/Model.h b/src/apps/haiku-depot/Model.h index 390c0a6c39..f6f5087c20 100644 --- a/src/apps/haiku-depot/Model.h +++ b/src/apps/haiku-depot/Model.h @@ -5,6 +5,7 @@ #ifndef MODEL_H #define MODEL_H +#include #include "PackageInfo.h" @@ -24,6 +25,9 @@ class Model { public: Model(); + BLocker* Lock() + { return &fLock; } + // !Returns new PackageInfoList from current parameters PackageList CreatePackageList() const; @@ -63,7 +67,12 @@ public: void SetDepot(const BString& depot); void SetSearchTerms(const BString& searchTerms); + // Retrieve package information + void PopulatePackage(const PackageInfoRef& package); + private: + BLocker fLock; + DepotList fDepots; CategoryRef fCategoryAudio; @@ -84,6 +93,7 @@ private: PackageList fUninstalledPackages; PackageList fDownloadingPackages; PackageList fUpdateablePackages; + PackageList fPopulatedPackages; PackageFilterRef fCategoryFilter; BString fDepotFilter; diff --git a/src/apps/haiku-depot/PackageInfoView.cpp b/src/apps/haiku-depot/PackageInfoView.cpp index 51b92c51e5..d040ee26d7 100644 --- a/src/apps/haiku-depot/PackageInfoView.cpp +++ b/src/apps/haiku-depot/PackageInfoView.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -1122,12 +1123,77 @@ private: }; +// #pragma mark - PackageInfoViewListener + + +enum { + MSG_UPDATE_PACKAGE = 'updp' +}; + + +class PackageInfoView::Listener : public PackageInfoListener { +public: + Listener(PackageInfoView* view) + : + fView(view) + { + } + + virtual ~Listener() + { + } + + virtual void PackageChanged(const PackageInfoEvent& event) + { + BMessenger messenger(fView); + if (!messenger.IsValid()) + return; + + const PackageInfo& package = *event.Package().Get(); + + BMessage message(MSG_UPDATE_PACKAGE); + message.AddString("title", package.Title()); + message.AddUInt32("changes", event.Changes()); + + messenger.SendMessage(&message); + } + + void SetPackage(const PackageInfoRef& package) + { + if (fPackage == package) + return; + + PackageInfoListenerRef listener(this); + + if (fPackage.Get() != NULL) + fPackage->RemoveListener(listener); + + fPackage = package; + + if (fPackage.Get() != NULL) + fPackage->AddListener(listener); + } + + const PackageInfoRef& Package() const + { + return fPackage; + } + +private: + PackageInfoView* fView; + PackageInfoRef fPackage; +}; + + // #pragma mark - PackageInfoView -PackageInfoView::PackageInfoView(PackageManager* packageManager) +PackageInfoView::PackageInfoView(BLocker* modelLock, + PackageManager* packageManager) : - BGroupView("package info view", B_VERTICAL) + BGroupView("package info view", B_VERTICAL), + fModelLock(modelLock), + fPackageListener(new(std::nothrow) Listener(this)) { fTitleView = new TitleView(); fPackageActionView = new PackageActionView(packageManager); @@ -1150,6 +1216,8 @@ PackageInfoView::PackageInfoView(PackageManager* packageManager) PackageInfoView::~PackageInfoView() { + fPackageListener->SetPackage(PackageInfoRef(NULL)); + delete fPackageListener; } @@ -1163,6 +1231,35 @@ void PackageInfoView::MessageReceived(BMessage* message) { switch (message->what) { + case MSG_UPDATE_PACKAGE: + { + if (fPackageListener->Package().Get() == NULL) + break; + + BString title; + uint32 changes; + if (message->FindString("title", &title) != B_OK + || message->FindUInt32("changes", &changes) != B_OK) { + break; + } + + const PackageInfo& package = *fPackageListener->Package().Get(); + if (package.Title() != title) + break; + + BAutolock _(fModelLock); + + if ((changes & PKG_CHANGED_DESCRIPTION) != 0 + || (changes & PKG_CHANGED_SCREENSHOTS) != 0) { + fTitleView->SetPackage(package); + } + + if ((changes & PKG_CHANGED_RATINGS) != 0) { + fPagesView->SetPackage(package); + } + + break; + } default: BGroupView::MessageReceived(message); break; @@ -1171,14 +1268,20 @@ PackageInfoView::MessageReceived(BMessage* message) void -PackageInfoView::SetPackage(const PackageInfo& package) +PackageInfoView::SetPackage(const PackageInfoRef& packageRef) { + BAutolock _(fModelLock); + + const PackageInfo& package = *packageRef.Get(); + fTitleView->SetPackage(package); fPackageActionView->SetPackage(package); fPagesView->SetPackage(package); if (fPagesView->IsHidden(fPagesView)) fPagesView->Show(); + + fPackageListener->SetPackage(packageRef); } @@ -1191,5 +1294,9 @@ PackageInfoView::Clear() if (!fPagesView->IsHidden(fPagesView)) fPagesView->Hide(); + + BAutolock _(fModelLock); + + fPackageListener->SetPackage(PackageInfoRef(NULL)); } diff --git a/src/apps/haiku-depot/PackageInfoView.h b/src/apps/haiku-depot/PackageInfoView.h index ea871dda36..723fa7a266 100644 --- a/src/apps/haiku-depot/PackageInfoView.h +++ b/src/apps/haiku-depot/PackageInfoView.h @@ -8,8 +8,10 @@ #include #include "PackageInfo.h" +#include "PackageInfoListener.h" +class BLocker; class TitleView; class PackageActionView; class PackageManager; @@ -23,19 +25,27 @@ enum { class PackageInfoView : public BGroupView { public: - PackageInfoView(PackageManager* packageManager); + PackageInfoView(BLocker* modelLock, + PackageManager* packageManager); virtual ~PackageInfoView(); virtual void AttachedToWindow(); virtual void MessageReceived(BMessage* message); - void SetPackage(const PackageInfo& package); + void SetPackage(const PackageInfoRef& package); void Clear(); private: + class Listener; + +private: + BLocker* fModelLock; + TitleView* fTitleView; PackageActionView* fPackageActionView; PagesView* fPagesView; + + Listener* fPackageListener; }; #endif // PACKAGE_INFO_VIEW_H From b0fbddbd03794617503d1e75a1ef456b71ebbe19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 16 Sep 2013 22:11:06 +0200 Subject: [PATCH 094/137] HaikuDepot: Also lock the model when updating the list --- src/apps/haiku-depot/MainWindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/apps/haiku-depot/MainWindow.cpp b/src/apps/haiku-depot/MainWindow.cpp index 6b332b93aa..89544b4c0d 100644 --- a/src/apps/haiku-depot/MainWindow.cpp +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -154,6 +154,7 @@ MainWindow::_AdoptModel() fPackageListView->Clear(); for (int32 i = 0; i < fVisiblePackages.CountItems(); i++) { + BAutolock _(fModel.Lock()); fPackageListView->AddPackage(fVisiblePackages.ItemAtFast(i)); } } From bb4c532b7779934fdab117c7b5de29461c800bf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 16 Sep 2013 22:17:42 +0200 Subject: [PATCH 095/137] HaikuDepot: Fixed selecting the right package when the list is sorted. --- src/apps/haiku-depot/MainWindow.cpp | 17 +++++++++++++---- src/apps/haiku-depot/PackageListView.cpp | 9 ++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/apps/haiku-depot/MainWindow.cpp b/src/apps/haiku-depot/MainWindow.cpp index 89544b4c0d..662f28b9b8 100644 --- a/src/apps/haiku-depot/MainWindow.cpp +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -87,14 +88,22 @@ MainWindow::MessageReceived(BMessage* message) switch (message->what) { case B_SIMPLE_DATA: case B_REFS_RECEIVED: + // TODO: ? break; case MSG_PACKAGE_SELECTED: { - int32 index; - if (message->FindInt32("index", &index) == B_OK - && index >= 0 && index < fVisiblePackages.CountItems()) { - _AdoptPackage(fVisiblePackages.ItemAtFast(index)); + BString title; + if (message->FindString("title", &title) == B_OK) { + int count = fVisiblePackages.CountItems(); + for (int i = 0; i < count; i++) { + const PackageInfoRef& package + = fVisiblePackages.ItemAtFast(i); + if (package.Get() != NULL && package->Title() == title) { + _AdoptPackage(package); + break; + } + } } else { _ClearPackage(); } diff --git a/src/apps/haiku-depot/PackageListView.cpp b/src/apps/haiku-depot/PackageListView.cpp index f21f9f85b1..ba6b9c22fc 100644 --- a/src/apps/haiku-depot/PackageListView.cpp +++ b/src/apps/haiku-depot/PackageListView.cpp @@ -544,14 +544,9 @@ PackageListView::SelectionChanged() BMessage message(MSG_PACKAGE_SELECTED); - BRow* selected = CurrentSelection(); - - // TODO: Wrong index, its the visible one (i.e. sorted)! - // Solve by putting an ID for the package in the message instead. - int32 index = -1; + PackageRow* selected = dynamic_cast(CurrentSelection()); if (selected != NULL) - index = IndexOf(selected); - message.AddInt32("index", index); + message.AddString("title", selected->Package()->Title()); Window()->PostMessage(&message); } From 206313697f8d1763a453521cd99d021493535932 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 16 Sep 2013 22:38:29 +0200 Subject: [PATCH 096/137] Fix gcc2 build. --- .../debugger/user_interface/gui/inspector_window/MemoryView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp index 9a3947c7cf..8b5e782573 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp +++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp @@ -660,7 +660,7 @@ MemoryView::_GetOffsetAt(BPoint point) const if (fHexMode == HexModeNone) return -1; - int32 lineNumber = point.y / fLineHeight; + int32 lineNumber = int32(point.y / fLineHeight); int32 charsPerBlock = _GetHexDigitsPerBlock() / 2; int32 totalHexBlocks = fTargetBlock->Size() / charsPerBlock; int32 lineCount = totalHexBlocks / fHexBlocksPerLine; From bdd7ba66b535f8c428c84958c801c59216ac693e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 16 Sep 2013 23:16:52 +0200 Subject: [PATCH 097/137] BColumnListView: Enable invalidating rows, fix SetField() * Seems like there was no easy way to simply invalidate a given BRow. Introduced BColumnListView::InvalidateRow(). * BRow::SetField() tried to invalidate the row, but invalidated the listview instead of the BOutlineView responsible for drawing the list contents. Use the new InvaalidateRow(). --- headers/private/interface/ColumnListView.h | 4 ++++ src/kits/interface/ColumnListView.cpp | 21 ++++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/headers/private/interface/ColumnListView.h b/headers/private/interface/ColumnListView.h index 027154b98b..f262b09f47 100644 --- a/headers/private/interface/ColumnListView.h +++ b/headers/private/interface/ColumnListView.h @@ -135,6 +135,8 @@ public: bool IsExpanded() const; bool IsSelected() const; + void Invalidate(); + private: // Blows up into the debugger if the validation fails. void ValidateFields() const; @@ -332,6 +334,8 @@ public: parentRow1 = NULL, BRow* parentRow2 = NULL); void Clear(); + void InvalidateRow(BRow* row); + // Appearance (DEPRECATED) void GetFont(BFont* font) const { BView::GetFont(font); } diff --git a/src/kits/interface/ColumnListView.cpp b/src/kits/interface/ColumnListView.cpp index fd5c5747e8..eea89d49f6 100644 --- a/src/kits/interface/ColumnListView.cpp +++ b/src/kits/interface/ColumnListView.cpp @@ -500,9 +500,7 @@ BRow::SetField(BField* field, int32 logicalFieldIndex) if (NULL != fList) { ValidateField(field, logicalFieldIndex); - BRect inv; - fList->GetRowRect(this, &inv); - fList->Invalidate(inv); + Invalidate(); } fFields.AddItem(field, logicalFieldIndex); @@ -530,6 +528,14 @@ BRow::IsSelected() const } +void +BRow::Invalidate() +{ + if (fList != NULL) + fList->InvalidateRow(this); +} + + void BRow::ValidateFields() const { @@ -1340,6 +1346,15 @@ BColumnListView::Clear() } +void +BColumnListView::InvalidateRow(BRow* row) +{ + BRect updateRect; + GetRowRect(row, &updateRect); + fOutlineView->Invalidate(updateRect); +} + + void BColumnListView::SetFont(const BFont* font, uint32 mask) { From e69b2374f256601ce938a34c493f01331b5eb6d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 16 Sep 2013 23:18:59 +0200 Subject: [PATCH 098/137] HaikuDepot: Update package list when necessary * Pass the Model lock to the PackageListView. * Register a PackageInfoListener with every listed package. * Update the rating when it is fetched. --- src/apps/haiku-depot/MainWindow.cpp | 2 +- src/apps/haiku-depot/PackageListView.cpp | 132 +++++++++++++++++++++-- src/apps/haiku-depot/PackageListView.h | 11 +- 3 files changed, 133 insertions(+), 12 deletions(-) diff --git a/src/apps/haiku-depot/MainWindow.cpp b/src/apps/haiku-depot/MainWindow.cpp index 662f28b9b8..1f09cf575a 100644 --- a/src/apps/haiku-depot/MainWindow.cpp +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -40,7 +40,7 @@ MainWindow::MainWindow(BRect frame) _BuildMenu(menuBar); fFilterView = new FilterView(fModel); - fPackageListView = new PackageListView(); + fPackageListView = new PackageListView(fModel.Lock()); fPackageInfoView = new PackageInfoView(fModel.Lock(), &fPackageManager); fSplitView = new BSplitView(B_VERTICAL, 5.0f); diff --git a/src/apps/haiku-depot/PackageListView.cpp b/src/apps/haiku-depot/PackageListView.cpp index ba6b9c22fc..b46fefda15 100644 --- a/src/apps/haiku-depot/PackageListView.cpp +++ b/src/apps/haiku-depot/PackageListView.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -80,13 +81,58 @@ private: class PackageRow : public BRow { typedef BRow Inherited; public: - PackageRow(const PackageInfoRef& package); + PackageRow(const PackageInfoRef& package, + PackageListener* listener); + virtual ~PackageRow(); const PackageInfoRef& Package() const { return fPackage; } + void UpdateRating(); + private: PackageInfoRef fPackage; + PackageInfoListenerRef fPackageListener; +}; + + +enum { + MSG_UPDATE_PACKAGE = 'updp' +}; + + +class PackageListener : public PackageInfoListener { +public: + PackageListener(PackageListView* view) + : + fView(view) + { + } + + virtual ~PackageListener() + { + } + + virtual void PackageChanged(const PackageInfoEvent& event) + { + if ((event.Changes() & PKG_CHANGED_RATINGS) == 0) + return; + + BMessenger messenger(fView); + if (!messenger.IsValid()) + return; + + const PackageInfo& package = *event.Package().Get(); + + BMessage message(MSG_UPDATE_PACKAGE); + message.AddString("title", package.Title()); + message.AddUInt32("changes", event.Changes()); + + messenger.SendMessage(&message); + } + +private: + PackageListView* fView; }; @@ -374,15 +420,17 @@ enum { }; -PackageRow::PackageRow(const PackageInfoRef& packageRef) +PackageRow::PackageRow(const PackageInfoRef& packageRef, + PackageListener* packageListener) : Inherited(ceilf(be_plain_font->Size() * 1.8f)), - fPackage(packageRef) + fPackage(packageRef), + fPackageListener(packageListener) { if (packageRef.Get() == NULL) return; - const PackageInfo& package = *packageRef.Get(); + PackageInfo& package = *packageRef.Get(); // Package icon and title // NOTE: The icon BBitmap is referenced by the fPackage member. @@ -392,8 +440,7 @@ PackageRow::PackageRow(const PackageInfoRef& packageRef) SetField(new BBitmapStringField(icon, package.Title()), kTitleColumn); // Rating - RatingSummary summary = package.CalculateRatingSummary(); - SetField(new RatingField(summary.averageRating), kRatingColumn); + UpdateRating(); // Description SetField(new BStringField(package.ShortDescription()), kDescriptionColumn); @@ -405,6 +452,25 @@ PackageRow::PackageRow(const PackageInfoRef& packageRef) // Status // TODO: Fetch info about installed/deactivated/unintalled/... SetField(new BStringField("n/a"), kStatusColumn); + + package.AddListener(fPackageListener); +} + + +PackageRow::~PackageRow() +{ + if (fPackage.Get() != NULL) + fPackage->RemoveListener(fPackageListener); +} + + +void +PackageRow::UpdateRating() +{ + if (fPackage.Get() == NULL) + return; + RatingSummary summary = fPackage->CalculateRatingSummary(); + SetField(new RatingField(summary.averageRating), kRatingColumn); } @@ -492,9 +558,11 @@ private: // #pragma mark - PackageListView -PackageListView::PackageListView() +PackageListView::PackageListView(BLocker* modelLock) : - BColumnListView("package list view", 0, B_FANCY_BORDER, true) + BColumnListView("package list view", 0, B_FANCY_BORDER, true), + fModelLock(modelLock), + fPackageListener(new(std::nothrow) PackageListener(this)) { AddColumn(new PackageColumn(B_TRANSLATE("Name"), 150, 50, 300, B_TRUNCATE_MIDDLE), kTitleColumn); @@ -516,6 +584,8 @@ PackageListView::PackageListView() PackageListView::~PackageListView() { + Clear(); + delete fPackageListener; } @@ -530,6 +600,27 @@ void PackageListView::MessageReceived(BMessage* message) { switch (message->what) { + case MSG_UPDATE_PACKAGE: + { + BString title; + uint32 changes; + if (message->FindString("title", &title) != B_OK + || message->FindUInt32("changes", &changes) != B_OK) { + break; + } + + if ((changes & PKG_CHANGED_RATINGS) == 0) + break; + + BAutolock _(fModelLock); + + PackageRow* row = _FindRow(title); + if (row != NULL) + row->UpdateRating(); + + break; + } + default: BColumnListView::MessageReceived(message); break; @@ -561,8 +652,10 @@ PackageListView::AddPackage(const PackageInfoRef& package) if (packageRow != NULL) return; + BAutolock _(fModelLock); + // create the row for this package - packageRow = new PackageRow(package); + packageRow = new PackageRow(package, fPackageListener); // add the row, parent may be NULL (add at top level) AddRow(packageRow); @@ -592,3 +685,24 @@ PackageListView::_FindRow(const PackageInfoRef& package, PackageRow* parent) return NULL; } + +PackageRow* +PackageListView::_FindRow(const BString& packageTitle, PackageRow* parent) +{ + for (int32 i = CountRows(parent) - 1; i >= 0; i--) { + PackageRow* row = dynamic_cast(RowAt(i, parent)); + if (row != NULL && row->Package().Get() != NULL + && row->Package()->Title() == packageTitle) { + return row; + } + if (CountRows(row) > 0) { + // recurse into child rows + row = _FindRow(packageTitle, row); + if (row != NULL) + return row; + } + } + + return NULL; +} + diff --git a/src/apps/haiku-depot/PackageListView.h b/src/apps/haiku-depot/PackageListView.h index 86fdd714c9..d9c7f66595 100644 --- a/src/apps/haiku-depot/PackageListView.h +++ b/src/apps/haiku-depot/PackageListView.h @@ -8,11 +8,13 @@ #include #include +#include #include "PackageInfo.h" class PackageRow; +class PackageListener; enum { MSG_PACKAGE_SELECTED = 'pkgs', @@ -21,7 +23,7 @@ enum { class PackageListView : public BColumnListView { public: - PackageListView(); + PackageListView(BLocker* modelLock); virtual ~PackageListView(); virtual void AttachedToWindow(); @@ -34,10 +36,15 @@ public: private: PackageRow* _FindRow(const PackageInfoRef& package, PackageRow* parent = NULL); + PackageRow* _FindRow(const BString& packageTitle, + PackageRow* parent = NULL); + private: class ItemCountView; - + + BLocker* fModelLock; ItemCountView* fItemCountView; + PackageListener* fPackageListener; }; #endif // PACKAGE_LIST_VIEW_H From 74018092d0db34e537e509e77c1e763b542cc3df Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Mon, 16 Sep 2013 23:08:46 +0200 Subject: [PATCH 099/137] libroot: Make sure PTHREAD_STACK_MIN is in the allowed range --- src/system/libroot/posix/pthread/pthread_attr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/system/libroot/posix/pthread/pthread_attr.c b/src/system/libroot/posix/pthread/pthread_attr.c index f6a15ff5e6..fecb9fca5b 100644 --- a/src/system/libroot/posix/pthread/pthread_attr.c +++ b/src/system/libroot/posix/pthread/pthread_attr.c @@ -12,6 +12,8 @@ #include #include +#include + #include @@ -105,6 +107,8 @@ pthread_attr_setstacksize(pthread_attr_t *_attr, size_t stacksize) if (_attr == NULL || (attr = *_attr) == NULL) return B_BAD_VALUE; + STATIC_ASSERT(PTHREAD_STACK_MIN >= MIN_USER_STACK_SIZE + && PTHREAD_STACK_MIN <= MAX_USER_STACK_SIZE); if (stacksize < PTHREAD_STACK_MIN || stacksize > MAX_USER_STACK_SIZE) return B_BAD_VALUE; From f06af2e2f897af2a66cb6031c7b7e05770f9271e Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Mon, 16 Sep 2013 23:16:29 +0200 Subject: [PATCH 100/137] system: Use B_PAGE_SIZE to define stack sizes As korli suggested use B_PAGE_SIZE for defining stack size related definitions what seems to be more natural for them and also may help if we ever support an architecture with page size different than 4kB. --- headers/private/system/thread_defs.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/headers/private/system/thread_defs.h b/headers/private/system/thread_defs.h index 3d7a3c1654..c2cc881206 100644 --- a/headers/private/system/thread_defs.h +++ b/headers/private/system/thread_defs.h @@ -13,10 +13,10 @@ /** Size of the stack given to teams in user space */ #define USER_STACK_GUARD_SIZE (4 * B_PAGE_SIZE) // 16 kB -#define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024) // 16 MB -#define USER_STACK_SIZE (256 * 1024) // 256 kB -#define MIN_USER_STACK_SIZE (8 * 1024) // 8 kB -#define MAX_USER_STACK_SIZE (16 * 1024 * 1024) // 16 MB +#define MIN_USER_STACK_SIZE (2 * B_PAGE_SIZE) // 8 kB +#define MAX_USER_STACK_SIZE (4096 * B_PAGE_SIZE) // 16 MB +#define USER_MAIN_THREAD_STACK_SIZE MAX_USER_STACK_SIZE +#define USER_STACK_SIZE (64 * B_PAGE_SIZE) // 256 kB // The type of object a thread blocks on (thread::wait::type, set by From aca204991f6753d7779292ed8605359b14973aa9 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Mon, 16 Sep 2013 23:19:23 +0200 Subject: [PATCH 101/137] posix: Update PTHREAD_STACK_MIN to match MIN_USER_STACK_SIZE Thanks for pointing this out Pete! --- headers/posix/limits.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/headers/posix/limits.h b/headers/posix/limits.h index e010cf3ea2..cdd95283f8 100644 --- a/headers/posix/limits.h +++ b/headers/posix/limits.h @@ -43,7 +43,7 @@ #define PATH_MAX (1024) #define PIPE_MAX (512) #define PTHREAD_KEYS_MAX 256 -#define PTHREAD_STACK_MIN 4096 +#define PTHREAD_STACK_MIN (2 * PAGE_SIZE) #define SSIZE_MAX __HAIKU_SADDR_MAX #define TTY_NAME_MAX (256) #define TZNAME_MAX (32) From c21a3b20c9d716c2614171d49b274303fca4285d Mon Sep 17 00:00:00 2001 From: John Scipione Date: Mon, 16 Sep 2013 18:45:56 -0400 Subject: [PATCH 102/137] Revert "ScreenSaver: ScrollToSelection off-by-one" This reverts commit fb90f7ffe49c07e82cd8cf68012929c87319f656. Underlying issue fixed in hrev46066 --- src/preferences/screensaver/ScreenSaverWindow.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/preferences/screensaver/ScreenSaverWindow.cpp b/src/preferences/screensaver/ScreenSaverWindow.cpp index 2bd834dcd0..4d4303cc1a 100644 --- a/src/preferences/screensaver/ScreenSaverWindow.cpp +++ b/src/preferences/screensaver/ScreenSaverWindow.cpp @@ -583,8 +583,6 @@ ModulesView::DetachedFromWindow() void ModulesView::AttachedToWindow() { - PopulateScreenSaverList(); - fScreenSaversListView->SetTarget(this); fTestButton->SetTarget(this); fAddButton->SetTarget(this); @@ -594,8 +592,7 @@ ModulesView::AttachedToWindow() void ModulesView::AllAttached() { - fScreenSaversListView->ScrollToSelection(); - // This only works after the list view is attached + PopulateScreenSaverList(); fScreenSaversListView->Invoke(new BMessage(kMsgSaverSelected)); } From 7418443d1246959a5d89dad67d56b749a6708c6a Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Tue, 17 Sep 2013 02:42:58 +0200 Subject: [PATCH 103/137] loader/u-boot: fix alignment of uimage components. The "blobs" in a U-Boot uimage are aligned at 4 bytes, which we did not take into account. Found this when adding a 3rd blob containing the Flattened Device Tree for ARM. --- src/system/boot/platform/u-boot/uimage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/boot/platform/u-boot/uimage.cpp b/src/system/boot/platform/u-boot/uimage.cpp index dfe85a4242..0e2edd5c0e 100644 --- a/src/system/boot/platform/u-boot/uimage.cpp +++ b/src/system/boot/platform/u-boot/uimage.cpp @@ -55,7 +55,7 @@ image_multi_getimg(struct image_header *image, uint32 idx, uint32 *data, uint32 *size = ntohl(sizes[i]); return true; } - base += ntohl(sizes[i]); + base += (ntohl(sizes[i]) + 3) & ~3; } return false; } From af1c0b55ca4c6303ce2c2d8789442421ddda2bc8 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Tue, 17 Sep 2013 03:03:17 +0200 Subject: [PATCH 104/137] ARM: kernel: fix timer resolution and implement basic timekeeping. The previously used method for programming the timer did not take into account that our timespec is 64bit while the register we poke it into is 32 bit. Since the PXA (SoC in Verdex target) has a limited scale of resolution (us,ms,second) we dynamicly determine the one that we can most closely match, and set that. For f.ex. snooze to work however, we also need system_time to work. The current implementation uses a system timer at microsecond resolution to keep track of time. Although the code is far from perfect, committing it now before it gets lost, since I'm working on the infrastructure code to properly factor out the SoC specific code out of the core ARM architecture code (so the kernel can support more then our poor old Verdex QEMU target ;)) --- src/system/kernel/arch/arm/arch_timer.cpp | 72 +++++++++++++++++------ src/system/kernel/lib/arch/arm/Jamfile | 2 - 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/system/kernel/arch/arm/arch_timer.cpp b/src/system/kernel/arch/arm/arch_timer.cpp index 5cf8574279..6c291ed6bb 100644 --- a/src/system/kernel/arch/arm/arch_timer.cpp +++ b/src/system/kernel/arch/arm/arch_timer.cpp @@ -35,35 +35,63 @@ #define PXA_OSSR 0x05 #define PXA_OIER 0x07 #define PXA_OSCR4 0x10 +#define PXA_OSCR5 0x11 #define PXA_OSMR4 0x20 +#define PXA_OSMR5 0x21 #define PXA_OMCR4 0x30 +#define PXA_OMCR5 0x31 +#define PXA_RES_S (3 << 0) +#define PXA_RES_MS (1 << 1) +#define PXA_RES_US (1 << 2) -static area_id sPxaTimersArea; -static uint32 *sPxaTimersBase; +#define US2S(bt) ((bt) / 1000000ULL) +#define US2MS(bt) ((bt) / 1000ULL) +static area_id sPxaTimersArea = B_ERROR; +static uint32 *sPxaTimersBase = NULL; +static bigtime_t sSystemTime = 0; static int32 pxa_timer_interrupt(void *data) { - int32 ret = timer_interrupt(); - sPxaTimersBase[PXA_OSSR] |= (1 << 4); + if (sPxaTimersBase[PXA_OSSR] & (1 << 4)) { + sPxaTimersBase[PXA_OSSR] |= (1 << 4); + return timer_interrupt(); + } - return ret; + if (sPxaTimersBase[PXA_OSSR] & (1 << 5)) { + sPxaTimersBase[PXA_OSSR] |= (1 << 5); + sSystemTime += UINT_MAX + 1ULL; + } + + return B_HANDLED_INTERRUPT; } - void arch_timer_set_hardware_timer(bigtime_t timeout) { - TRACE(("arch_timer_set_hardware_timer(%lld)\n", timeout)); + uint32 val = timeout & UINT_MAX; + uint32 res = PXA_RES_US; - if (sPxaTimersBase) { - sPxaTimersBase[PXA_OIER] |= (1 << 4); - sPxaTimersBase[PXA_OMCR4] = 4; // set to exactly single milisecond resolution - sPxaTimersBase[PXA_OSMR4] = timeout; - sPxaTimersBase[PXA_OSCR4] = 0; // start counting from 0 again + if (timeout & ~UINT_MAX) { + // Does not fit, so scale resolution down to milliseconds + if (US2MS(timeout) & ~UINT_MAX) { + // Still does not fit, scale down to seconds as last ditch attempt + val = US2S(timeout) & UINT_MAX; + res = PXA_RES_S; + } else { + // Fits in millisecond resolution + val = US2MS(timeout) & UINT_MAX; + res = PXA_RES_MS; + } } + + TRACE(("arch_timer_set_hardware_timer(val=%lu, res=%lu)\n", val, res)); + sPxaTimersBase[PXA_OIER] |= (1 << 4); + sPxaTimersBase[PXA_OMCR4] = res; + sPxaTimersBase[PXA_OSMR4] = val; + sPxaTimersBase[PXA_OSCR4] = 0; // start counting from 0 again } @@ -72,13 +100,10 @@ arch_timer_clear_hardware_timer() { TRACE(("arch_timer_clear_hardware_timer\n")); - if (sPxaTimersBase) { - sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer - sPxaTimersBase[PXA_OIER] &= ~(4 << 1); - } + sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer + sPxaTimersBase[PXA_OIER] &= ~(1 << 4); } - int arch_init_timer(kernel_args *args) { @@ -88,9 +113,20 @@ arch_init_timer(kernel_args *args) if (sPxaTimersArea < 0) return sPxaTimersArea; - sPxaTimersBase[PXA_OMCR4] = 0; // disable our timer + sPxaTimersBase[PXA_OIER] |= (1 << 5); // enable timekeeping timer + sPxaTimersBase[PXA_OMCR5] = PXA_RES_US | (1 << 7); + sPxaTimersBase[PXA_OSMR5] = UINT_MAX; + sPxaTimersBase[PXA_OSCR5] = 0; install_io_interrupt_handler(PXA_TIMERS_INTERRUPT, &pxa_timer_interrupt, NULL, 0); return B_OK; } + +bigtime_t +system_time(void) +{ + return (sPxaTimersBase != NULL) ? + sSystemTime + sPxaTimersBase[PXA_OSCR5] : + 0ULL; +} diff --git a/src/system/kernel/lib/arch/arm/Jamfile b/src/system/kernel/lib/arch/arm/Jamfile index 084a552ca8..1bdf0f1501 100644 --- a/src/system/kernel/lib/arch/arm/Jamfile +++ b/src/system/kernel/lib/arch/arm/Jamfile @@ -11,8 +11,6 @@ SEARCH_SOURCE += [ FDirName $(librootSources) os arch generic ] ; KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o : atomic.S byteorder.S -# system_time_asm.S - system_time.c generic_system_time_nsecs.cpp From 00e13e215e687183d8192b339232c941bddb5c8f Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Tue, 17 Sep 2013 05:26:29 +0200 Subject: [PATCH 105/137] norflash: do not accept any device as a valid 'norflash' Seems the original code was a little *too* simple ;-) --- src/add-ons/kernel/drivers/disk/norflash/norflash.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp b/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp index 4bd20bd48c..1fd7be7e40 100644 --- a/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp +++ b/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp @@ -165,8 +165,16 @@ nor_write(void *_cookie, off_t position, const void *data, size_t *numbytes) static float nor_supports_device(device_node *parent) { + const char *bus; TRACE("supports_device\n"); - return 0.6; + + if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) + return B_ERROR; + + if (strcmp(bus, "generic")) + return 0.0; + + return 1.0; } From f2479c22a8fc50b3086c63d2c823621d39c183ba Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Tue, 17 Sep 2013 05:50:05 +0200 Subject: [PATCH 106/137] device_manager: Move init_node_tree to after kdl cmd registration This helps when debugging, since when a driver/module causes a crash while registering with the device manager, you can actually look at the device manager state ;-) --- src/system/kernel/device_manager/device_manager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/device_manager/device_manager.cpp b/src/system/kernel/device_manager/device_manager.cpp index e73c025e95..5de0b31d71 100644 --- a/src/system/kernel/device_manager/device_manager.cpp +++ b/src/system/kernel/device_manager/device_manager.cpp @@ -2280,7 +2280,6 @@ device_manager_init(struct kernel_args* args) dm_init_io_resources(); recursive_lock_init(&sLock, "device manager"); - init_node_tree(); register_generic_syscall(DEVICE_MANAGER_SYSCALLS, control_device_manager, 1, 0); @@ -2300,6 +2299,9 @@ device_manager_init(struct kernel_args* args) "dump an I/O operation"); add_debugger_command("io_buffer", &dump_io_buffer, "dump an I/O buffer"); add_debugger_command("dma_buffer", &dump_dma_buffer, "dump a DMA buffer"); + + init_node_tree(); + return B_OK; } From a82e311cf19cd5493798b6164e2246f1b78c8bfa Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Tue, 17 Sep 2013 11:14:38 +0200 Subject: [PATCH 107/137] Debugger: Fix calculation in MemoryView. - The offset calculation for mapping the current point wasn't taking into account the number of bytes per hex block, causing it to be proportionally further off if one switched to 16/32/64-bit hex mode. Gets mouse selection working properly in said modes. --- .../debugger/user_interface/gui/inspector_window/MemoryView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp index 8b5e782573..7f5111531c 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp +++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp @@ -677,7 +677,7 @@ MemoryView::_GetOffsetAt(BPoint point) const float blockWidth = (charsPerBlock * 2 + 1) * fCharWidth; int32 containingBlock = int32(floor(point.x / blockWidth)); - return fHexBlocksPerLine * lineNumber + return fHexBlocksPerLine * charsPerBlock * lineNumber + containingBlock * charsPerBlock; } From 4ce4250be08c334d7aa6e9008d0108afb7bdbf0b Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Tue, 17 Sep 2013 11:17:31 +0200 Subject: [PATCH 108/137] Debugger: Fix RegistersView context menu. - Always grab the address value from the actual register value column, rather than the one that's in fact under the mouse. Fixes the "Inspect" item sending you to inspect address 0 if you happened to right click over the register name rather than the value. --- .../debugger/user_interface/gui/team_window/RegistersView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp b/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp index 031bb6ba9b..9dafae441d 100644 --- a/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/RegistersView.cpp @@ -242,7 +242,7 @@ RegistersView::TableCellMouseDown(Table* table, int32 rowIndex, return; BVariant value; - if (!fRegisterTableModel->GetValueAt(rowIndex, columnIndex, value)) + if (!fRegisterTableModel->GetValueAt(rowIndex, 1, value)) return; BPopUpMenu* menu = new(std::nothrow)BPopUpMenu("Options"); From 5ad39153e3e408483ddc076641a0f6425bafc07a Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Tue, 17 Sep 2013 12:07:52 +0200 Subject: [PATCH 109/137] Debugger: MemoryView - Tweak target address drawing. - Since we actually draw a selection now, change the target address highlight to clearly distinguish it. Rather than inverting it, it's now drawn with a normal background and red text in the hex display. The text mode subcomponent still shows it as an invert though, since the latter doesn't currently indicate the selection. --- .../gui/inspector_window/MemoryView.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp index 7f5111531c..8aaec0a1ff 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp +++ b/src/apps/debugger/user_interface/gui/inspector_window/MemoryView.cpp @@ -185,17 +185,14 @@ MemoryView::Draw(BRect rect) const char* blockAddress = currentAddress + (j * blockByteSize); _GetNextHexBlock(buffer, sizeof(buffer), blockAddress); - DrawString(buffer, drawPoint); if (targetAddress >= blockAddress && targetAddress < - blockAddress + blockByteSize) { + blockAddress + blockByteSize) { PushState(); - SetHighColor(B_TRANSPARENT_COLOR); - SetDrawingMode(B_OP_INVERT); - FillRect(BRect(drawPoint.x, drawPoint.y - fh.ascent, - drawPoint.x + (hexBlockSize - 1) * fCharWidth, - drawPoint.y + fh.descent)); + SetHighColor(make_color(216,0,0)); + DrawString(buffer, drawPoint); PopState(); - } + } else + DrawString(buffer, drawPoint); drawPoint.x += fCharWidth * hexBlockSize; } From c55cff0acc4bd544d05059833ca909385a5a2f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 17 Sep 2013 13:51:38 +0200 Subject: [PATCH 110/137] Whitespace cleanup --- src/system/boot/platform/u-boot/arch/ppc/arch_mmu.cpp | 8 ++++---- src/system/kernel/arch/ppc/arch_exceptions_44x.S | 4 ++-- src/system/kernel/platform/u-boot/fdt_support.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/system/boot/platform/u-boot/arch/ppc/arch_mmu.cpp b/src/system/boot/platform/u-boot/arch/ppc/arch_mmu.cpp index b58cb7fd7d..10bdc1a53a 100644 --- a/src/system/boot/platform/u-boot/arch/ppc/arch_mmu.cpp +++ b/src/system/boot/platform/u-boot/arch/ppc/arch_mmu.cpp @@ -64,11 +64,11 @@ 0x01900000 boot.tgz (= ramdisk) 0x02000000 boot loader uimage - - boot loader heap (should be discarded later on) - ... 256M-Kstack page hash table + + boot loader heap (should be discarded later on) + ... 256M-Kstack page hash table ... 256M kernel stack - kernel stack guard page + kernel stack guard page The kernel is mapped at KERNEL_BASE, all other stuff mapped by the loader (kernel args, modules, driver settings, ...) comes after diff --git a/src/system/kernel/arch/ppc/arch_exceptions_44x.S b/src/system/kernel/arch/ppc/arch_exceptions_44x.S index c4a1a60afa..c533bcaaf5 100644 --- a/src/system/kernel/arch/ppc/arch_exceptions_44x.S +++ b/src/system/kernel/arch/ppc/arch_exceptions_44x.S @@ -287,7 +287,7 @@ __44x_save_regs: stwu %r0, -4(%r1) /* push r3 */ /* push r4-r31 */ - stwu %r4, -4(%r1) + stwu %r4, -4(%r1) stwu %r5, -4(%r1) stwu %r6, -4(%r1) stwu %r7, -4(%r1) @@ -393,7 +393,7 @@ __44x_restore_regs_and_rfi: lwzu %r5, 4(%r1) lwzu %r4, 4(%r1) lwzu %r3, 4(%r1) - + /* Stop here, before we overwrite r1, and continue with the floating point registers first. */ addi %r2, %r1, 16 /* skip r3-r0 */ diff --git a/src/system/kernel/platform/u-boot/fdt_support.cpp b/src/system/kernel/platform/u-boot/fdt_support.cpp index df4c79bde9..63e92dc3dd 100644 --- a/src/system/kernel/platform/u-boot/fdt_support.cpp +++ b/src/system/kernel/platform/u-boot/fdt_support.cpp @@ -69,7 +69,7 @@ void dump_fdt(const void *fdt) int err; dprintf("FDT @ %p:\n", fdt); - + if (!fdt) return; From 09d213f3b37465cd0f5c034de2023e8ca46881b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 17 Sep 2013 15:49:49 +0200 Subject: [PATCH 111/137] PPC: OF: Make sure kernel args match the U-Boot one Since both platforms can boot the same kernel we must accept either arg, so we make sure they are identical for now. TODO: use a union or KMessage maybe? --- .../boot/platform/openfirmware/platform_kernel_args.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/headers/private/kernel/boot/platform/openfirmware/platform_kernel_args.h b/headers/private/kernel/boot/platform/openfirmware/platform_kernel_args.h index 94c8ab6c31..150afe25c3 100644 --- a/headers/private/kernel/boot/platform/openfirmware/platform_kernel_args.h +++ b/headers/private/kernel/boot/platform/openfirmware/platform_kernel_args.h @@ -19,6 +19,12 @@ typedef struct { void *openfirmware_entry; char rtc_path[128]; + + // XXX: HACK: must match the U-Boot platform args + // FIXME: use a union instead? + + // Flattened Device Tree blob + void *fdt; } platform_kernel_args; #endif /* KERNEL_BOOT_PLATFORM_OPENFIRMWARE_KERNEL_ARGS_H */ From 34ed0fe74aa9d8b0b432ee165000ab04c97f3dcf Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Tue, 17 Sep 2013 15:56:32 +0200 Subject: [PATCH 112/137] ARM: kernel: fix system_time() when being called too early. --- src/system/kernel/arch/arm/arch_timer.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/system/kernel/arch/arm/arch_timer.cpp b/src/system/kernel/arch/arm/arch_timer.cpp index 6c291ed6bb..01a6fb2f9a 100644 --- a/src/system/kernel/arch/arm/arch_timer.cpp +++ b/src/system/kernel/arch/arm/arch_timer.cpp @@ -29,7 +29,7 @@ #define PXA_TIMERS_PHYS_BASE 0x40A00000 -#define PXA_TIMERS_SIZE 0x000000C0 +#define PXA_TIMERS_SIZE B_PAGE_SIZE #define PXA_TIMERS_INTERRUPT 7 /* OST_4_11 */ #define PXA_OSSR 0x05 @@ -48,7 +48,7 @@ #define US2S(bt) ((bt) / 1000000ULL) #define US2MS(bt) ((bt) / 1000ULL) -static area_id sPxaTimersArea = B_ERROR; +static area_id sPxaTimersArea = -1; static uint32 *sPxaTimersBase = NULL; static bigtime_t sSystemTime = 0; @@ -107,6 +107,7 @@ arch_timer_clear_hardware_timer() int arch_init_timer(kernel_args *args) { + TRACE(("%s\n", __func__)); sPxaTimersArea = map_physical_memory("pxa_timers", PXA_TIMERS_PHYS_BASE, PXA_TIMERS_SIZE, 0, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, (void**)&sPxaTimersBase); @@ -126,6 +127,9 @@ arch_init_timer(kernel_args *args) bigtime_t system_time(void) { + if (sPxaTimersArea < 0) + return 0; + return (sPxaTimersBase != NULL) ? sSystemTime + sPxaTimersBase[PXA_OSCR5] : 0ULL; From 7de035619bf4e660f3f2243b343de4dffc7ab79b Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Tue, 17 Sep 2013 18:08:21 +0200 Subject: [PATCH 113/137] Debugger: Fix off by one error in report generator. - The disassembly dump would consequently stop at the instruction prior to the actual crash culprit, and also erroneously mark it as such. --- src/apps/debugger/controllers/DebugReportGenerator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/debugger/controllers/DebugReportGenerator.cpp b/src/apps/debugger/controllers/DebugReportGenerator.cpp index 60cdba9026..bf45375753 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.cpp +++ b/src/apps/debugger/controllers/DebugReportGenerator.cpp @@ -566,9 +566,9 @@ DebugReportGenerator::_DumpFunctionDisassembly(BString& _output, SourceLocation location = statement->StartSourceLocation(); _output << "\t\t\tDisassembly:\n"; - for (int32 i = 0; i < location.Line(); i++) { + for (int32 i = 0; i <= location.Line(); i++) { _output << "\t\t\t\t" << code->LineAt(i); - if (i == location.Line() - 1) + if (i == location.Line()) _output << " <--"; _output << "\n"; } From 740490ba82249ed10d726738771cd9ec5f86f174 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Tue, 17 Sep 2013 22:24:57 +0200 Subject: [PATCH 114/137] ARM: libroot: fix setjmp/longjmp implementation. Just a couple of lines of code, but a head full of pain ;-) Finally got it right and now KDL can properly recover from invalid accesses. --- .../libroot/posix/arch/arm/siglongjmp.S | 9 ++---- src/system/libroot/posix/arch/arm/sigsetjmp.S | 30 +++++++------------ 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/src/system/libroot/posix/arch/arm/siglongjmp.S b/src/system/libroot/posix/arch/arm/siglongjmp.S index 07fe6fd06a..9101e23bb8 100644 --- a/src/system/libroot/posix/arch/arm/siglongjmp.S +++ b/src/system/libroot/posix/arch/arm/siglongjmp.S @@ -5,16 +5,13 @@ #include -//#include "setjmp_internal.h" - /* int __siglongjmp(jmp_buf buffer, int value) */ FUNCTION(siglongjmp): FUNCTION(longjmp): FUNCTION(_longjmp): - str r1,[r0] - ldmia r0,{r0-r14} - bx lr -// bl __longjmp_return + str r1, [r0, #4] + ldmia r0, {r0-r14} + b __longjmp_return FUNCTION_END(siglongjmp) FUNCTION_END(longjmp) FUNCTION_END(_longjmp) diff --git a/src/system/libroot/posix/arch/arm/sigsetjmp.S b/src/system/libroot/posix/arch/arm/sigsetjmp.S index bf77eadf4e..74e046d87e 100644 --- a/src/system/libroot/posix/arch/arm/sigsetjmp.S +++ b/src/system/libroot/posix/arch/arm/sigsetjmp.S @@ -5,33 +5,25 @@ #include -//#include "setjmp_internal.h" - /* int sigsetjmp(jmp_buf buffer, int saveMask) */ FUNCTION(__sigsetjmp): FUNCTION(sigsetjmp): - stmdb sp!, {r4, lr} - stmia r0, {r0-r14} - str lr,[r0, #60] - mrs r1,cpsr - str r1,[r0,#64] - ldr r1,[r0,#4] - mov r0, #0 - - bl __setjmp_save_sigs - ldmia sp!, {r4, pc} -FUNCTION_END(__sigsetjmp) + stmia r0, {r0-r14} + mrs r1, cpsr + str r1, [r0, #64] + ldr r1, [r0, #4] + b __setjmp_save_sigs FUNCTION_END(sigsetjmp) +FUNCTION_END(__sigsetjmp) /* int setjmp(jmp_buf buffer) */ FUNCTION(setjmp): - stmia r0, {r0-r14} - str lr,[r0, #60] - mrs r1,cpsr - str r1,[r0,#64] - ldr r1,[r0,#4] - mov r0, #0 + stmia r0, {r0-r14} + mrs r1, cpsr + str r1, [r0, #64] + ldr r1, [r0, #4] + mov r0, #0 bx lr FUNCTION_END(setjmp) From cc65466f0de34d946d9311517f4e7781b7294ef8 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Tue, 17 Sep 2013 23:04:59 +0200 Subject: [PATCH 115/137] ARM: kernel: Make KDL more useful on ARM This adds the -mapcs-frame compiler flag for ARM to have "stable" stack frames, adds support to the kernel for dumping stack crawls, and initial support for iframes. There' much more functionality to unlock in KDL, but this makes debugging already a lot more comfortable..... --- build/jam/BuildSetup | 2 + headers/private/kernel/arch/arm/arch_cpu.h | 1 + src/system/kernel/arch/arm/arch_asm.S | 6 + src/system/kernel/arch/arm/arch_debug.cpp | 436 ++++++++++++++++----- src/system/kernel/arch/arm/arch_int.cpp | 36 ++ src/system/kernel/arch/arm/arch_thread.cpp | 17 + 6 files changed, 390 insertions(+), 108 deletions(-) diff --git a/build/jam/BuildSetup b/build/jam/BuildSetup index 47f346fb9a..6eb5b937aa 100644 --- a/build/jam/BuildSetup +++ b/build/jam/BuildSetup @@ -242,6 +242,8 @@ switch $(HAIKU_CPU) { case arm : { HAIKU_DEFINES += __ARM__ ; + HAIKU_CCFLAGS += -mapcs-frame ; # For stackcrawls + HAIKU_C++FLAGS += -mapcs-frame ; HAIKU_BOOT_PLATFORM ?= u-boot ; HAIKU_BOOT_BOARD ?= verdex ; HAIKU_BOOT_FLOPPY_IMAGE_SIZE = 1440 ; diff --git a/headers/private/kernel/arch/arm/arch_cpu.h b/headers/private/kernel/arch/arm/arch_cpu.h index a70398aa64..fea6c68979 100644 --- a/headers/private/kernel/arch/arm/arch_cpu.h +++ b/headers/private/kernel/arch/arm/arch_cpu.h @@ -63,6 +63,7 @@ extern "C" { extern addr_t arm_get_far(void); extern int32 arm_get_fsr(void); +extern addr_t arm_get_fp(void); extern int mmu_read_c1(void); extern int mmu_write_c1(int val); diff --git a/src/system/kernel/arch/arm/arch_asm.S b/src/system/kernel/arch/arm/arch_asm.S index 689f615646..50e9508274 100644 --- a/src/system/kernel/arch/arm/arch_asm.S +++ b/src/system/kernel/arch/arm/arch_asm.S @@ -94,6 +94,12 @@ FUNCTION(arm_get_far): bx lr FUNCTION_END(arm_get_far) +/* addr_t arm_get_fp(void); */ +FUNCTION(arm_get_fp): + mov r0, fp @ get framepointer + bx lr +FUNCTION_END(arm_get_fp); + /* status_t arch_cpu_user_memcpy(void *to, const void *from, size_t size, addr_t *faultHandler) */ FUNCTION(arch_cpu_user_memcpy): stmfd sp!, { r4-r6 } diff --git a/src/system/kernel/arch/arm/arch_debug.cpp b/src/system/kernel/arch/arm/arch_debug.cpp index daae859148..1832ca2962 100644 --- a/src/system/kernel/arch/arm/arch_debug.cpp +++ b/src/system/kernel/arch/arm/arch_debug.cpp @@ -6,6 +6,8 @@ * Axel Dörfler * Ingo Weinhold * François Revol + * Ithamar R. Adema + * */ @@ -13,25 +15,22 @@ #include #include +#include #include #include #include #include - - -struct stack_frame { - struct stack_frame *previous; - addr_t return_address; -}; +#include +#include +#include #define NUM_PREVIOUS_LOCATIONS 32 extern struct iframe_stack gBootFrameStack; -/* static bool -already_visited(uint32 *visited, int32 *_last, int32 *_num, uint32 framePointer) +already_visited(uint32 *visited, int32 *_last, int32 *_num, uint32 fp) { int32 last = *_last; int32 num = *_num; @@ -39,13 +38,13 @@ already_visited(uint32 *visited, int32 *_last, int32 *_num, uint32 framePointer) for (i = 0; i < num; i++) { if (visited[(NUM_PREVIOUS_LOCATIONS + last - i) - % NUM_PREVIOUS_LOCATIONS] == framePointer) { + % NUM_PREVIOUS_LOCATIONS] == fp) { return true; } } *_last = last = (last + 1) % NUM_PREVIOUS_LOCATIONS; - visited[last] = framePointer; + visited[last] = fp; if (num < NUM_PREVIOUS_LOCATIONS) *_num = num + 1; @@ -54,99 +53,327 @@ already_visited(uint32 *visited, int32 *_last, int32 *_num, uint32 framePointer) } -static inline stack_frame * -get_current_stack_frame() +static status_t +get_next_frame(addr_t fp, addr_t *next, addr_t *ip) { - stack_frame *frame; - asm volatile("move.l %%fp,%0" : "=r"(frame)); - return frame; + if (fp != 0) { + addr_t _fp = *(((addr_t*)fp) -3); + addr_t _sp = *(((addr_t*)fp) -2); + addr_t _lr = *(((addr_t*)fp) -1); + addr_t _pc = *(((addr_t*)fp) -0); + + *ip = (_fp != 0) ? _lr : _pc; + *next = _fp; + + return B_OK; + } + + return B_BAD_VALUE; } static status_t -get_next_frame(addr_t framePointer, addr_t *next, addr_t *ip) +lookup_symbol(Thread* thread, addr_t address, addr_t* _baseAddress, + const char** _symbolName, const char** _imageName, bool* _exactMatch) { - Thread *thread = thread_get_current_thread(); - addr_t oldFaultHandler = thread->fault_handler; + status_t status = B_ENTRY_NOT_FOUND; - // set fault handler, so that we can safely access user stacks - if (thread) { - if (m68k_set_fault_handler(&thread->fault_handler, (addr_t)&&error)) - goto error; + if (IS_KERNEL_ADDRESS(address)) { + // a kernel symbol + status = elf_debug_lookup_symbol_address(address, _baseAddress, + _symbolName, _imageName, _exactMatch); + } else if (thread != NULL && thread->team != NULL) { + // try a lookup using the userland runtime loader structures + status = elf_debug_lookup_user_symbol_address(thread->team, address, + _baseAddress, _symbolName, _imageName, _exactMatch); + + if (status != B_OK) { + // try to locate the image in the images loaded into user space + status = image_debug_lookup_user_symbol_address(thread->team, + address, _baseAddress, _symbolName, _imageName, _exactMatch); + } } - *ip = ((struct stack_frame *)framePointer)->return_address; - *next = (addr_t)((struct stack_frame *)framePointer)->previous; - - if (thread) - thread->fault_handler = oldFaultHandler; - return B_OK; - -error: - thread->fault_handler = oldFaultHandler; - return B_BAD_ADDRESS; + return status; } static void -print_stack_frame(Thread *thread, addr_t ip, addr_t framePointer, - addr_t nextFramePointer) +set_debug_argument_variable(int32 index, uint64 value) { - addr_t diff = nextFramePointer - framePointer; - - // kernel space/user space switch - if (diff & 0x80000000) - diff = 0; - - // lookup symbol - const char *symbol, *image; - addr_t baseAddress; - bool exactMatch; - status_t status = elf_debug_lookup_symbol_address(ip, &baseAddress, &symbol, - &image, &exactMatch); - if (status != B_OK && !IS_KERNEL_ADDRESS(ip) && thread) { - // try to locate the image in the images loaded into user space - status = image_debug_lookup_user_symbol_address(thread->team, ip, - &baseAddress, &symbol, &image, &exactMatch); - } - if (status == B_OK) { - if (symbol != NULL) { - kprintf("%08lx (+%4ld) %08lx <%s>:%s + 0x%04lx%s\n", framePointer, - diff, ip, image, symbol, ip - baseAddress, - (exactMatch ? "" : " (nearest)")); - } else { - kprintf("%08lx (+%4ld) %08lx <%s@%p>:unknown + 0x%04lx\n", - framePointer, diff, ip, image, (void *)baseAddress, - ip - baseAddress); - } - } else - kprintf("%08lx (+%4ld) %08lx\n", framePointer, diff, ip); + char name[8]; + snprintf(name, sizeof(name), "_arg%ld", index); + set_debug_variable(name, value); } +template +static Type +read_function_argument_value(void* argument, bool& _valueKnown) +{ + Type value; + if (debug_memcpy(B_CURRENT_TEAM, &value, argument, sizeof(Type)) == B_OK) { + _valueKnown = true; + return value; + } + + _valueKnown = false; + return 0; +} + + +static status_t +print_demangled_call(const char* image, const char* symbol, addr_t args, + bool noObjectMethod, bool addDebugVariables) +{ + static const size_t kBufferSize = 256; + char* buffer = (char*)debug_malloc(kBufferSize); + if (buffer == NULL) + return B_NO_MEMORY; + + bool isObjectMethod; + const char* name = debug_demangle_symbol(symbol, buffer, kBufferSize, + &isObjectMethod); + if (name == NULL) { + debug_free(buffer); + return B_ERROR; + } + + uint32* arg = (uint32*)args; + + if (noObjectMethod) + isObjectMethod = false; + if (isObjectMethod) { + const char* lastName = strrchr(name, ':') - 1; + int namespaceLength = lastName - name; + + uint32 argValue = 0; + if (debug_memcpy(B_CURRENT_TEAM, &argValue, arg, 4) == B_OK) { + kprintf("<%s> %.*s<\33[32m%#" B_PRIx32 "\33[0m>%s", image, + namespaceLength, name, argValue, lastName); + } else + kprintf("<%s> %.*s%s", image, namespaceLength, name, lastName); + + if (addDebugVariables) + set_debug_variable("_this", argValue); + arg++; + } else + kprintf("<%s> %s", image, name); + + kprintf("("); + + size_t length; + int32 type, i = 0; + uint32 cookie = 0; + while (debug_get_next_demangled_argument(&cookie, symbol, buffer, + kBufferSize, &type, &length) == B_OK) { + if (i++ > 0) + kprintf(", "); + + // retrieve value and type identifier + + uint64 value; + bool valueKnown = false; + + switch (type) { + case B_INT64_TYPE: + value = read_function_argument_value(arg, valueKnown); + if (valueKnown) + kprintf("int64: \33[34m%Ld\33[0m", value); + break; + case B_INT32_TYPE: + value = read_function_argument_value(arg, valueKnown); + if (valueKnown) + kprintf("int32: \33[34m%ld\33[0m", (int32)value); + break; + case B_INT16_TYPE: + value = read_function_argument_value(arg, valueKnown); + if (valueKnown) + kprintf("int16: \33[34m%d\33[0m", (int16)value); + break; + case B_INT8_TYPE: + value = read_function_argument_value(arg, valueKnown); + if (valueKnown) + kprintf("int8: \33[34m%d\33[0m", (int8)value); + break; + case B_UINT64_TYPE: + value = read_function_argument_value(arg, valueKnown); + if (valueKnown) { + kprintf("uint64: \33[34m%#Lx\33[0m", value); + if (value < 0x100000) + kprintf(" (\33[34m%Lu\33[0m)", value); + } + break; + case B_UINT32_TYPE: + value = read_function_argument_value(arg, valueKnown); + if (valueKnown) { + kprintf("uint32: \33[34m%#lx\33[0m", (uint32)value); + if (value < 0x100000) + kprintf(" (\33[34m%lu\33[0m)", (uint32)value); + } + break; + case B_UINT16_TYPE: + value = read_function_argument_value(arg, valueKnown); + if (valueKnown) { + kprintf("uint16: \33[34m%#x\33[0m (\33[34m%u\33[0m)", + (uint16)value, (uint16)value); + } + break; + case B_UINT8_TYPE: + value = read_function_argument_value(arg, valueKnown); + if (valueKnown) { + kprintf("uint8: \33[34m%#x\33[0m (\33[34m%u\33[0m)", + (uint8)value, (uint8)value); + } + break; + case B_BOOL_TYPE: + value = read_function_argument_value(arg, valueKnown); + if (valueKnown) + kprintf("\33[34m%s\33[0m", value ? "true" : "false"); + break; + default: + if (buffer[0]) + kprintf("%s: ", buffer); + + if (length == 4) { + value = read_function_argument_value(arg, + valueKnown); + if (valueKnown) { + if (value == 0 + && (type == B_POINTER_TYPE || type == B_REF_TYPE)) + kprintf("NULL"); + else + kprintf("\33[34m%#lx\33[0m", (uint32)value); + } + break; + } + + + if (length == 8) { + value = read_function_argument_value(arg, + valueKnown); + } else + value = (uint64)arg; + + if (valueKnown) + kprintf("\33[34m%#Lx\33[0m", value); + break; + } + + if (!valueKnown) + kprintf("???"); + + if (valueKnown && type == B_STRING_TYPE) { + if (value == 0) + kprintf(" \33[31m\"\"\33[0m"); + else if (debug_strlcpy(B_CURRENT_TEAM, buffer, (char*)(addr_t)value, + kBufferSize) < B_OK) { + kprintf(" \33[31m\"\"\33[0m"); + } else + kprintf(" \33[36m\"%s\"\33[0m", buffer); + } + + if (addDebugVariables) + set_debug_argument_variable(i, value); + arg = (uint32*)((uint8*)arg + length); + } + + debug_free(buffer); + + kprintf(")"); + return B_OK; +} + + + +static void +print_stack_frame(Thread *thread, addr_t ip, addr_t fp, addr_t next, + int32 callIndex, bool demangle) +{ + const char* symbol; + const char* image; + addr_t baseAddress; + bool exactMatch; + status_t status; + addr_t diff; + + diff = next - fp; + + // MSB set = kernel space/user space switch + if (diff & ~((addr_t)-1 >> 1)) + diff = 0; + + status = lookup_symbol(thread, ip, &baseAddress, &symbol, &image, + &exactMatch); + + kprintf("%2" B_PRId32 " %0*lx (+%4ld) %0*lx ", callIndex, + B_PRINTF_POINTER_WIDTH, fp, diff, B_PRINTF_POINTER_WIDTH, ip); + + if (status == B_OK) { + if (exactMatch && demangle) { + status = print_demangled_call(image, symbol, + next, false, false); + } + + if (!exactMatch || !demangle || status != B_OK) { + if (symbol != NULL) { + kprintf("<%s> %s%s", image, symbol, + exactMatch ? "" : " (nearest)"); + } else + kprintf("<%s@%p> ", image, (void*)baseAddress); + } + + kprintf(" + %#04lx\n", ip - baseAddress); + } else { + VMArea *area = NULL; + if (thread != NULL && thread->team != NULL + && thread->team->address_space != NULL) { + area = thread->team->address_space->LookupArea(ip); + } + if (area != NULL) { + kprintf("%" B_PRId32 ":%s@%p + %#lx\n", area->id, area->name, + (void*)area->Base(), ip - area->Base()); + } else + kprintf("\n"); + } +} + static int stack_trace(int argc, char **argv) { - uint32 previousLocations[NUM_PREVIOUS_LOCATIONS]; - struct iframe_stack *frameStack; - Thread *thread; - addr_t framePointer; - int32 i, num = 0, last = 0; - - if (argc < 2) { - thread = thread_get_current_thread(); - framePointer = (addr_t)get_current_stack_frame(); - } else { -kprintf("Stack traces of other threads not supported yet!\n"); -return 0; + static const char* usage = "usage: %s [-d] [ ]\n" + "Prints a stack trace for the current, respectively the specified\n" + "thread.\n" + " -d - Disables the demangling of the symbols.\n" + " - The ID of the thread for which to print the stack\n" + " trace.\n"; + bool demangle = true; + int32 threadIndex = 1; + if (argc > 1 && !strcmp(argv[1], "-d")) { + demangle = false; + threadIndex++; } + if (argc > threadIndex + 1 + || (argc == 2 && strcmp(argv[1], "--help") == 0)) { + kprintf(usage, argv[0]); + return 0; + } + + addr_t previousLocations[NUM_PREVIOUS_LOCATIONS]; + Thread* thread = NULL; + phys_addr_t oldPageDirectory = 0; + addr_t fp = arm_get_fp(); + int32 num = 0, last = 0; + struct iframe_stack *frameStack; + // We don't have a thread pointer early in the boot process if (thread != NULL) frameStack = &thread->arch_info.iframes; else frameStack = &gBootFrameStack; + int32 i; for (i = 0; i < frameStack->index; i++) { kprintf("iframe %p (end = %p)\n", frameStack->frames[i], frameStack->frames[i] + 1); @@ -168,11 +395,11 @@ return 0; kprintf("frame caller :function + offset\n"); - for (;;) { + for (int32 callIndex = 0;; callIndex++) { // see if the frame pointer matches the iframe struct iframe *frame = NULL; for (i = 0; i < frameStack->index; i++) { - if (framePointer == (addr_t)frameStack->frames[i]) { + if (fp == (addr_t)frameStack->frames[i]) { // it's an iframe frame = frameStack->frames[i]; break; @@ -181,49 +408,43 @@ return 0; if (frame) { kprintf("iframe at %p\n", frame); - kprintf(" d0 0x%08lx d1 0x%08lx d2 0x%08lx d3 0x%08lx\n", - frame->d[0], frame->d[1], frame->d[2], frame->d[3]); - kprintf(" d4 0x%08lx d5 0x%08lx d6 0x%08lx d7 0x%08lx\n", - frame->d[4], frame->d[5], frame->d[6], frame->d[7]); - kprintf(" a0 0x%08lx a1 0x%08lx a2 0x%08lx a3 0x%08lx\n", - frame->a[0], frame->a[1], frame->a[2], frame->a[3]); - kprintf(" a4 0x%08lx a5 0x%08lx a6 0x%08lx a7 0x%08lx (sp)\n", -#warning M68K: a7 in iframe ?? - frame->a[4], frame->a[5], frame->a[6], -1L); - kprintf(" pc 0x%08lx sr 0x%04x\n", - frame->cpu.pc, frame->cpu.sr); -#warning M68K: missing regs + kprintf(" r0 0x%08lx r1 0x%08lx r2 0x%08lx r3 0x%08lx\n", + frame->r0, frame->r1, frame->r2, frame->r3); + kprintf(" r4 0x%08lx r5 0x%08lx r6 0x%08lx r7 0x%08lx\n", + frame->r4, frame->r5, frame->r6, frame->r7); + kprintf(" r8 0x%08lx r9 0x%08lx r10 0x%08lx r11 0x%08lx\n", + frame->r8, frame->r9, frame->r10, frame->r11); + kprintf(" r12 0x%08lx sp 0x%08lx lr 0x%08lx pc 0x%08lx\n", + frame->r12, frame->svc_sp, frame->svc_lr, frame->pc); - print_stack_frame(thread, frame->cpu.pc, framePointer, frame->a[6]); - framePointer = frame->a[6]; + fp = frame->svc_sp; + print_stack_frame(thread, frame->pc, frame->svc_sp, frame->svc_lr, callIndex, demangle); } else { - addr_t ip, nextFramePointer; + addr_t ip, next; - if (get_next_frame(framePointer, &nextFramePointer, &ip) != B_OK) { - kprintf("%08lx -- read fault\n", framePointer); + if (get_next_frame(fp, &next, &ip) != B_OK) { + kprintf("%08lx -- read fault\n", fp); break; } - if (ip == 0 || framePointer == 0) + if (ip == 0 || fp == 0) break; - print_stack_frame(thread, ip, framePointer, nextFramePointer); - framePointer = nextFramePointer; + print_stack_frame(thread, ip, fp, next, callIndex, demangle); + fp = next; } - if (already_visited(previousLocations, &last, &num, framePointer)) { - kprintf("circular stack frame: %p!\n", (void *)framePointer); + if (already_visited(previousLocations, &last, &num, fp)) { + kprintf("circular stack frame: %p!\n", (void *)fp); break; } - if (framePointer == 0) + if (fp == 0) break; } - return 0; } -*/ // #pragma mark - @@ -245,6 +466,7 @@ arch_debug_contains_call(Thread *thread, const char *symbol, void arch_debug_stack_trace(void) { + stack_trace(0, NULL); } @@ -261,8 +483,7 @@ int32 arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount, int32 skipIframes, int32 skipFrames, uint32 flags) { -#warning ARM:IMPLEMENT - + // TODO: Implement! return 0; } @@ -302,10 +523,9 @@ arch_get_debug_variable(const char* variableName, uint64* value) status_t arch_debug_init(kernel_args *args) { -// add_debugger_command("where", &stack_trace, "Same as \"sc\""); -// add_debugger_command("bt", &stack_trace, "Same as \"sc\" (as in gdb)"); -// add_debugger_command("sc", &stack_trace, "Stack crawl for current thread"); -#warning ARM:IMPLEMENT + add_debugger_command("where", &stack_trace, "Same as \"sc\""); + add_debugger_command("bt", &stack_trace, "Same as \"sc\" (as in gdb)"); + add_debugger_command("sc", &stack_trace, "Stack crawl for current thread"); return B_NO_ERROR; } diff --git a/src/system/kernel/arch/arm/arch_int.cpp b/src/system/kernel/arch/arm/arch_int.cpp index b41cc7154d..0dc4fdcd9f 100644 --- a/src/system/kernel/arch/arm/arch_int.cpp +++ b/src/system/kernel/arch/arm/arch_int.cpp @@ -188,9 +188,35 @@ arch_int_init_post_device_manager(struct kernel_args *args) } +// Little helper class for handling the +// iframe stack as used by KDL. +class IFrameScope { +public: + IFrameScope(struct iframe *iframe) { + fThread = thread_get_current_thread(); + if (fThread) + arm_push_iframe(&fThread->arch_info.iframes, iframe); + else + arm_push_iframe(&gBootFrameStack, iframe); + } + + virtual ~IFrameScope() { + // pop iframe + if (fThread) + arm_pop_iframe(&fThread->arch_info.iframes); + else + arm_pop_iframe(&gBootFrameStack); + } +private: + Thread* fThread; +}; + + extern "C" void arch_arm_undefined(struct iframe *iframe) { + IFrameScope scope(iframe); // push/pop iframe + print_iframe("Undefined Instruction", iframe); panic("not handled!"); } @@ -199,6 +225,8 @@ arch_arm_undefined(struct iframe *iframe) extern "C" void arch_arm_syscall(struct iframe *iframe) { + IFrameScope scope(iframe); // push/pop iframe + print_iframe("Software interrupt", iframe); } @@ -206,6 +234,8 @@ arch_arm_syscall(struct iframe *iframe) extern "C" void arch_arm_data_abort(struct iframe *frame) { + IFrameScope scope(iframe); + Thread *thread = thread_get_current_thread(); bool isUser = (frame->spsr & 0x1f) == 0x10; addr_t far = arm_get_far(); @@ -290,6 +320,8 @@ arch_arm_data_abort(struct iframe *frame) extern "C" void arch_arm_prefetch_abort(struct iframe *iframe) { + IFrameScope scope(iframe); + print_iframe("Prefetch Abort", iframe); panic("not handled!"); } @@ -298,6 +330,8 @@ arch_arm_prefetch_abort(struct iframe *iframe) extern "C" void arch_arm_irq(struct iframe *iframe) { + IFrameScope scope(iframe); + for (int i=0; i < 32; i++) { if (sPxaInterruptBase[PXA_ICIP] & (1 << i)) int_io_interrupt_handler(i, true); @@ -308,6 +342,8 @@ arch_arm_irq(struct iframe *iframe) extern "C" void arch_arm_fiq(struct iframe *iframe) { + IFrameScope scope(iframe); + for (int i=0; i < 32; i++) { if (sPxaInterruptBase[PXA_ICIP] & (1 << i)) { dprintf("arch_arm_fiq: help me, FIQ %d was triggered but no " diff --git a/src/system/kernel/arch/arm/arch_thread.cpp b/src/system/kernel/arch/arm/arch_thread.cpp index 3f7950e380..2de87612e8 100644 --- a/src/system/kernel/arch/arm/arch_thread.cpp +++ b/src/system/kernel/arch/arm/arch_thread.cpp @@ -42,6 +42,23 @@ static struct arch_thread sInitialState; Thread *gCurrentThread; +void +arm_push_iframe(struct iframe_stack *stack, struct iframe *frame) +{ + ASSERT(stack->index < IFRAME_TRACE_DEPTH); + stack->frames[stack->index++] = frame; +} + + +void +arm_pop_iframe(struct iframe_stack *stack) +{ + ASSERT(stack->index > 0); + stack->index--; +} + + + status_t arch_thread_init(struct kernel_args *args) { From 501b24c63b267527538aa4a7591348b3832bb84d Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Wed, 18 Sep 2013 05:03:18 +0200 Subject: [PATCH 116/137] ARM: kernel: Make 32/64-bit atomics work for ARMv5/6 Support for 64-bit atomic operations for ARMv7+ is currently stubbed out in libroot, but our current targets do not use it anyway. We now select atomics-as-syscalls automatically based on the ARM architecture we're building for. The intent is to do away with most of the board specifics (at the very least on the kernel side) and just specify the lowest ARMvX version you want to build for. This will give flexibility in being able to distribute a single image for a wide range of devices, and building a tuned system for one specific core type. --- headers/private/system/arch/arm/arch_config.h | 10 +- src/system/kernel/arch/arm/Jamfile | 5 +- src/system/kernel/arch/arm/arch_atomic32.cpp | 177 ++++++++++++++++ src/system/kernel/arch/arm/arch_atomic64.cpp | 192 ++++++++++++++++++ src/system/libroot/os/arch/arm/atomic.S | 95 +-------- 5 files changed, 389 insertions(+), 90 deletions(-) create mode 100644 src/system/kernel/arch/arm/arch_atomic32.cpp create mode 100644 src/system/kernel/arch/arm/arch_atomic64.cpp diff --git a/headers/private/system/arch/arm/arch_config.h b/headers/private/system/arch/arm/arch_config.h index 409f58dfc0..5e203811bb 100644 --- a/headers/private/system/arch/arm/arch_config.h +++ b/headers/private/system/arch/arm/arch_config.h @@ -10,8 +10,14 @@ #define STACK_GROWS_DOWNWARDS -//#define ATOMIC_FUNCS_ARE_SYSCALLS -//#define ATOMIC64_FUNCS_ARE_SYSCALLS +// If we're building on ARMv5 or older, all our atomics need to be syscalls... :( +#if _M_ARM <= 5 +#define ATOMIC_FUNCS_ARE_SYSCALLS +#endif +// If we're building on ARMv6 or older, 64-bit atomics need to be syscalls... +#if _M_ARM < 7 +#define ATOMIC64_FUNCS_ARE_SYSCALLS +#endif #endif /* _KERNEL_ARCH_ARM_CONFIG_H */ diff --git a/src/system/kernel/arch/arm/Jamfile b/src/system/kernel/arch/arm/Jamfile index 25e4f8a42c..8386a7596f 100644 --- a/src/system/kernel/arch/arm/Jamfile +++ b/src/system/kernel/arch/arm/Jamfile @@ -10,10 +10,8 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) paging 32bit ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ; KernelMergeObject kernel_arch_arm.o : -# arch_atomic.c arch_commpage.cpp arch_cpu.cpp -# arch_cpu_asm.S arch_debug_console.cpp arch_debug.cpp arch_elf.cpp @@ -33,6 +31,9 @@ KernelMergeObject kernel_arch_arm.o : arch_uart_8250.cpp arch_uart_pl011.cpp + arch_atomic64.cpp + arch_atomic32.cpp + # paging arm_physical_page_mapper.cpp arm_physical_page_mapper_large_memory.cpp diff --git a/src/system/kernel/arch/arm/arch_atomic32.cpp b/src/system/kernel/arch/arm/arch_atomic32.cpp new file mode 100644 index 0000000000..df10e72bed --- /dev/null +++ b/src/system/kernel/arch/arm/arch_atomic32.cpp @@ -0,0 +1,177 @@ +/* + * Copyright 2013 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Ithamar R. Adema, ithamar@upgrade-android.com + */ + +#include + +#include +#include + +#include + +#ifdef ATOMIC_FUNCS_ARE_SYSCALLS + +/* + * NOTE: These functions are _intentionally_ not using spinlocks, unlike + * the 64 bit versions. The reason for this is that they are used by the + * spinlock code itself, and therefore would deadlock. + * + * Since these are only really needed for ARMv5, which is not SMP anyway, + * this is an acceptable compromise. + */ + +int32 +atomic_set(vint32 *value, int32 newValue) +{ + InterruptsLocker locker; + + int32 oldValue = *value; + *value = newValue; + return oldValue; +} + +int32 +atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst) +{ + InterruptsLocker locker; + + int32 oldValue = *value; + if (oldValue == testAgainst) + *value = newValue; + return oldValue; +} + +int32 +atomic_add(vint32 *value, int32 addValue) +{ + InterruptsLocker locker; + + int32 oldValue = *value; + *value += addValue; + return oldValue; +} + +int32 +atomic_and(vint32 *value, int32 andValue) +{ + InterruptsLocker locker; + + int32 oldValue = *value; + *value &= andValue; + return oldValue; +} + +int32 +atomic_or(vint32 *value, int32 orValue) +{ + InterruptsLocker locker; + + int32 oldValue = *value; + *value |= orValue; + return oldValue; +} + +int32 +atomic_get(vint32 *value) +{ + InterruptsLocker locker; + + int32 oldValue = *value; + return oldValue; +} + +int32 +_user_atomic_set(vint32 *value, int32 newValue) +{ + if (IS_USER_ADDRESS(value) + && lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) { + int32 oldValue = atomic_set(value, newValue); + unlock_memory((void *)value, sizeof(int32), B_READ_DEVICE); + return oldValue; + } + +access_violation: + // XXX kill application + return -1; +} + +int32 +_user_atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst) +{ + if (IS_USER_ADDRESS(value) + && lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) { + int32 oldValue = atomic_test_and_set(value, newValue, testAgainst); + unlock_memory((void *)value, sizeof(int32), B_READ_DEVICE); + return oldValue; + } + +access_violation: + // XXX kill application + return -1; +} + +int32 +_user_atomic_add(vint32 *value, int32 addValue) +{ + if (IS_USER_ADDRESS(value) + && lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) { + int32 oldValue = atomic_add(value, addValue); + unlock_memory((void *)value, sizeof(int32), B_READ_DEVICE); + return oldValue; + } + +access_violation: + // XXX kill application + return -1; +} + +int32 +_user_atomic_and(vint32 *value, int32 andValue) +{ + if (IS_USER_ADDRESS(value) + && lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) { + int32 oldValue = atomic_and(value, andValue); + unlock_memory((void *)value, sizeof(int32), B_READ_DEVICE); + return oldValue; + } + +access_violation: + // XXX kill application + return -1; +} + +int32 +_user_atomic_or(vint32 *value, int32 orValue) +{ + if (IS_USER_ADDRESS(value) + && lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) { + int32 oldValue = atomic_or(value, orValue); + unlock_memory((void *)value, sizeof(int32), B_READ_DEVICE); + return oldValue; + } + +access_violation: + // XXX kill application + return -1; +} + +int32 +_user_atomic_get(vint32 *value) +{ + if (IS_USER_ADDRESS(value) + && lock_memory((void *)value, sizeof(int32), B_READ_DEVICE) == B_OK) { + int32 oldValue = atomic_get(value); + unlock_memory((void *)value, sizeof(int32), B_READ_DEVICE); + return oldValue; + } + +access_violation: + // XXX kill application + return -1; +} + +#endif /* ATOMIC_FUNCS_ARE_SYSCALLS */ diff --git a/src/system/kernel/arch/arm/arch_atomic64.cpp b/src/system/kernel/arch/arm/arch_atomic64.cpp new file mode 100644 index 0000000000..a57fd61c6d --- /dev/null +++ b/src/system/kernel/arch/arm/arch_atomic64.cpp @@ -0,0 +1,192 @@ +/* + * Copyright 2013 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Ithamar R. Adema, ithamar@upgrade-android.com + */ + +#include + +#include +#include + +#include + +#ifdef ATOMIC64_FUNCS_ARE_SYSCALLS + +/* + * NOTE: Unlike their 32-bit counterparts, these functions can use + * spinlocks safely currently, as no atomic 64-bit operations are + * done in the spinlock code. If this ever changes, this code will + * have to change. + * + * This code is here for ARMv6, which cannot do proper 64-bit atomic + * operations. Anything newer is capable, and does therefore not + * depend on this code. + */ + + +static spinlock atomic_lock = B_SPINLOCK_INITIALIZER; + + +int64 +atomic_set64(vint64 *value, int64 newValue) +{ + SpinLocker locker(&atomic_lock); + + int64 oldValue = *value; + *value = newValue; + return oldValue; +} + + +int64 +atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst) +{ + SpinLocker locker(&atomic_lock); + + int64 oldValue = *value; + if (oldValue == testAgainst) + *value = newValue; + return oldValue; +} + + +int64 +atomic_add64(vint64 *value, int64 addValue) +{ + SpinLocker locker(&atomic_lock); + + int64 oldValue = *value; + *value += addValue; + return oldValue; +} + + +int64 +atomic_and64(vint64 *value, int64 andValue) +{ + SpinLocker locker(&atomic_lock); + + int64 oldValue = *value; + *value &= andValue; + return oldValue; +} + + +int64 +atomic_or64(vint64 *value, int64 orValue) +{ + SpinLocker locker(&atomic_lock); + + int64 oldValue = *value; + *value |= orValue; + return oldValue; +} + + +int64 +atomic_get64(vint64 *value) +{ + SpinLocker locker(&atomic_lock); + return *value; +} + + +int64 +_user_atomic_set64(vint64 *value, int64 newValue) +{ + if (IS_USER_ADDRESS(value) + && lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) { + int64 oldValue = atomic_set64(value, newValue); + unlock_memory((void *)value, sizeof(int64), B_READ_DEVICE); + return oldValue; + } + +access_violation: + // XXX kill application + return -1; +} + + +int64 +_user_atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst) +{ + if (IS_USER_ADDRESS(value) + && lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) { + int64 oldValue = atomic_test_and_set64(value, newValue, testAgainst); + unlock_memory((void *)value, sizeof(int64), B_READ_DEVICE); + return oldValue; + } + +access_violation: + // XXX kill application + return -1; +} + + +int64 +_user_atomic_add64(vint64 *value, int64 addValue) +{ + if (IS_USER_ADDRESS(value) + && lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) { + int64 oldValue = atomic_add64(value, addValue); + unlock_memory((void *)value, sizeof(int64), B_READ_DEVICE); + return oldValue; + } + +access_violation: + // XXX kill application + return -1; +} + + +int64 +_user_atomic_and64(vint64 *value, int64 andValue) +{ + if (IS_USER_ADDRESS(value) + && lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) { + int64 oldValue = atomic_and64(value, andValue); + unlock_memory((void *)value, sizeof(int64), B_READ_DEVICE); + return oldValue; + } + +access_violation: + // XXX kill application + return -1; +} + + +int64 +_user_atomic_or64(vint64 *value, int64 orValue) +{ + if (IS_USER_ADDRESS(value) + && lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) { + int64 oldValue = atomic_or64(value, orValue); + unlock_memory((void *)value, sizeof(int64), B_READ_DEVICE); + return oldValue; + } + +access_violation: + // XXX kill application + return -1; +} + + +int64 +_user_atomic_get64(vint64 *value) +{ + if (IS_USER_ADDRESS(value) + && lock_memory((void *)value, sizeof(int64), B_READ_DEVICE) == B_OK) { + int64 oldValue = atomic_get64(value); + unlock_memory((void *)value, sizeof(int64), B_READ_DEVICE); + return oldValue; + } + +access_violation: + // XXX kill application + return -1; +} + +#endif /* ATOMIC64_FUNCS_ARE_SYSCALLS */ diff --git a/src/system/libroot/os/arch/arm/atomic.S b/src/system/libroot/os/arch/arm/atomic.S index 795e89961d..f27bfd7223 100644 --- a/src/system/libroot/os/arch/arm/atomic.S +++ b/src/system/libroot/os/arch/arm/atomic.S @@ -4,14 +4,15 @@ */ #include - +#include .text +#ifndef ATOMIC_FUNCS_ARE_SYSCALLS + /* int atomic_add(int *value, int increment) */ FUNCTION(atomic_add): -#if __ARM_ARCH__ >= 6 miss1: ldrex r12, [r0] add r2, r12, r1 strex r3, r2, [r0] @@ -19,25 +20,6 @@ miss1: ldrex r12, [r0] bne miss1 mov r0, r12 bx lr -#else - /* disable interrupts, do the add, and reenable */ - mrs r2, cpsr - mov r12, r2 - orr r2, r2, #(3<<6) - msr cpsr_c, r2 - - /* ints disabled, old cpsr state in r12 */ - - /* do the add, leave the previous value in r0 */ - mov r3, r0 - ldr r0, [r3] - add r2, r0, r1 - str r2, [r3] - - /* restore interrupts and exit */ - msr cpsr_c, r12 - bx lr -#endif FUNCTION_END(atomic_add) @@ -46,7 +28,6 @@ FUNCTION_END(atomic_add) /* int atomic_and(int *value, int andValue) */ FUNCTION(atomic_and): -#if __ARM_ARCH__ >= 6 miss2: ldrex r12, [r0] and r2, r12, r1 strex r3, r2, [r0] @@ -54,33 +35,11 @@ miss2: ldrex r12, [r0] bne miss2 mov r0, r12 bx lr -#else - /* disable interrupts, do the and, and reenable */ - mrs r2, cpsr - mov r12, r2 - orr r2, r2, #(3<<6) - msr cpsr_c, r2 - - /* ints disabled, old cpsr state in r12 */ - - /* do the and, leave the previous value in r0 */ - mov r3, r0 - ldr r0, [r3] - and r2, r0, r1 - str r2, [r3] - - /* restore interrupts and exit */ - msr cpsr_c, r12 - bx lr -#endif - FUNCTION_END(atomic_and) /* int atomic_or(int *value, int orValue) */ FUNCTION(atomic_or): -#if __ARM_ARCH__ >= 6 - miss3: ldrex r12, [r0] eor r2, r12, r1 strex r3, r2, [r0] @@ -88,48 +47,21 @@ miss3: ldrex r12, [r0] bne miss3 mov r0, r12 bx lr -#else - /* disable interrupts, do the or, and reenable */ - mrs r2, cpsr - mov r12, r2 - orr r2, r2, #(3<<6) - msr cpsr_c, r2 - - /* ints disabled, old cpsr state in r12 */ - - /* do the or, leave the previous value in r0 */ - mov r3, r0 - ldr r0, [r3] - orr r2, r0, r1 - str r2, [r3] - - /* restore interrupts and exit */ - msr cpsr_c, r12 - bx lr -#endif - FUNCTION_END(atomic_or) /* int atomic_set(int *value, int setTo) */ FUNCTION(atomic_set): -#if __ARM_ARCH__ >= 6 miss4: ldrex r12, [r0] strex r3, r1, [r0] teq r3, #0 bne miss4 bx lr -#else - mov r3, r0 - swp r0, r1, [r3] - bx lr -#endif FUNCTION_END(atomic_set) /* int atomic_test_and_set(int *value, int setTo, int testValue) */ FUNCTION(atomic_test_and_set): -#if __ARM_ARCH__ >= 6 miss5: ldrex r12, [r0] @ load from the address and mark it exclusive cmp r12, r2 @ compare the value with the comperand(r2) strexeq r3, r1, [r0] @ if they were equal, attempt to store the new value (r1) @@ -139,21 +71,6 @@ miss5: ldrex r12, [r0] @ load from the address and bne same @ if it succeeded, jump to (same) and return. there is no need to clrex if strex succeeded differ: clrex @ clrex same: mov r0, r12 -#else - /* disable interrupts, and save state */ - mrs r3, cpsr - mov r12, r3 - orr r3, r3, #(3<<6) - msr cpsr_c, r3 - - mov r3, r0 - ldr r0, [r3] - cmp r0, r2 - streq r1, [r3] - - /* restore interrupts and exit */ - msr cpsr_c, r12 -#endif bx lr FUNCTION_END(atomic_test_and_set) @@ -168,6 +85,10 @@ FUNCTION(__sync_fetch_and_add_4): bx lr FUNCTION_END(__sync_fetch_and_add_4) +#endif + +#ifndef ATOMIC64_FUNCS_ARE_SYSCALLS + /* int64 atomic_add64(vint64 *value, int64 addValue) */ FUNCTION(atomic_add64): bx lr @@ -197,3 +118,5 @@ FUNCTION_END(atomic_test_and_set64) FUNCTION(atomic_get64): bx lr FUNCTION_END(atomic_get64) + +#endif /* ATOMIC64_FUNCS_ARE_SYSCALLS */ From 7416b5878f62ef0c1871e53607ccfebdc82f86b8 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Wed, 18 Sep 2013 06:33:57 +0200 Subject: [PATCH 117/137] ARM: verdex: Make sure __XSCALE__ is defined when compiling. This is especially important for the assembler code in the kernel, since it enables workarounds for some critical errata related to exception handling. --- build/jam/board/verdex/BoardSetup | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/build/jam/board/verdex/BoardSetup b/build/jam/board/verdex/BoardSetup index 4d56beefbb..fb3e69f509 100644 --- a/build/jam/board/verdex/BoardSetup +++ b/build/jam/board/verdex/BoardSetup @@ -68,10 +68,11 @@ HAIKU_BOARD_SDIMAGE_FILES = # gcc flags for the specific cpu # -HAIKU_KERNEL_CCFLAGS += -mcpu=xscale ; -HAIKU_KERNEL_C++FLAGS += -mcpu=xscale ; -HAIKU_CCFLAGS += -mcpu=xscale ; -HAIKU_C++FLAGS += -mcpu=xscale ; +HAIKU_KERNEL_CCFLAGS += -mcpu=xscale -D__XSCALE__ ; +HAIKU_KERNEL_C++FLAGS += -mcpu=xscale -D__XSCALE__ ; +HAIKU_CCFLAGS += -mcpu=xscale -D__XSCALE__ ; +HAIKU_C++FLAGS += -mcpu=xscale -D__XSCALE__ ; +TARGET_ASFLAGS += -mcpu=xscale -D__XSCALE__ ; # Workaround for ld using 32k for alignment despite forcing it in the config... # should definitely not be needed! From 33f263cb01e82be571639584a3fe6a690b583467 Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Mon, 16 Sep 2013 17:09:00 +0200 Subject: [PATCH 118/137] virtio: add queue_is_full(), queue_is_empty(), queue_size() hooks. --- headers/private/virtio/virtio.h | 6 ++++ .../bus_managers/virtio/VirtioModule.cpp | 30 ++++++++++++++++++- .../bus_managers/virtio/VirtioPrivate.h | 1 + 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/headers/private/virtio/virtio.h b/headers/private/virtio/virtio.h index 03792426b4..12691a1e52 100644 --- a/headers/private/virtio/virtio.h +++ b/headers/private/virtio/virtio.h @@ -117,6 +117,12 @@ typedef struct { size_t readVectorCount, size_t writtenVectorCount, virtio_callback_func callback, void *callbackCookie); + bool (*queue_is_full)(virtio_queue queue); + + bool (*queue_is_empty)(virtio_queue queue); + + uint16 (*queue_size)(virtio_queue queue); + } virtio_device_interface; diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioModule.cpp b/src/add-ons/kernel/bus_managers/virtio/VirtioModule.cpp index f2a284e96e..41b5860365 100644 --- a/src/add-ons/kernel/bus_managers/virtio/VirtioModule.cpp +++ b/src/add-ons/kernel/bus_managers/virtio/VirtioModule.cpp @@ -134,6 +134,31 @@ virtio_queue_request(virtio_queue cookie, const physical_entry *readEntry, } +bool +virtio_queue_is_full(virtio_queue cookie) +{ + VirtioQueue *queue = (VirtioQueue *)cookie; + return queue->IsFull(); +} + + +bool +virtio_queue_is_empty(virtio_queue cookie) +{ + VirtioQueue *queue = (VirtioQueue *)cookie; + return queue->IsEmpty(); +} + + +uint16 +virtio_queue_size(virtio_queue cookie) +{ + VirtioQueue *queue = (VirtioQueue *)cookie; + return queue->Size(); +} + + + // #pragma mark - @@ -222,7 +247,10 @@ virtio_device_interface virtio_device_module = { virtio_alloc_queues, virtio_setup_interrupt, virtio_queue_request, - virtio_queue_request_v + virtio_queue_request_v, + virtio_queue_is_full, + virtio_queue_is_empty, + virtio_queue_size }; virtio_for_controller_interface virtio_for_controller_module = { diff --git a/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h b/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h index a83eaf8058..4e0e0d132e 100644 --- a/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h +++ b/src/add-ons/kernel/bus_managers/virtio/VirtioPrivate.h @@ -107,6 +107,7 @@ public: bool IsFull() const { return fRingFree == 0; } bool IsEmpty() const { return fRingFree == fRingSize; } + uint16 Size() const { return fRingSize; } VirtioDevice* Device() { return fDevice; } From bd3bcbe5d6f544a4c9ce93cf28c29fd9e88abbe9 Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Wed, 18 Sep 2013 18:26:26 +0200 Subject: [PATCH 119/137] hda: reorganized the code for sense checking. * should help with #9965 --- .../kernel/drivers/audio/hda/hda_codec.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp b/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp index b8ff560260..4cdd2225a6 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/hda_codec.cpp @@ -1154,7 +1154,7 @@ TRACE("build tree!\n"); static void -hda_codec_switch_init(hda_audio_group* audioGroup) +hda_audio_group_switch_init(hda_audio_group* audioGroup) { for (uint32 i = 0; i < audioGroup->widget_count; i++) { hda_widget& widget = audioGroup->widgets[i]; @@ -1175,10 +1175,8 @@ hda_codec_switch_init(hda_audio_group* audioGroup) static void -hda_codec_check_sense(hda_codec* codec, bool disable) +hda_audio_group_check_sense(hda_audio_group* audioGroup, bool disable) { - hda_audio_group* audioGroup = codec->audio_groups[0]; - for (uint32 i = 0; i < audioGroup->widget_count; i++) { hda_widget& widget = audioGroup->widgets[i]; @@ -1233,7 +1231,8 @@ hda_codec_switch_handler(hda_codec* codec) codec->unsol_response_read %= MAX_CODEC_UNSOL_RESPONSES; bool disable = response & 1; - hda_codec_check_sense(codec, disable); + hda_audio_group* audioGroup = codec->audio_groups[0]; + hda_audio_group_check_sense(audioGroup, disable); } return B_OK; } @@ -1285,8 +1284,8 @@ hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID) if (hda_audio_group_build_tree(audioGroup) != B_OK) goto err; - hda_codec_switch_init(audioGroup); - + hda_audio_group_switch_init(audioGroup); + audioGroup->playback_stream = hda_stream_new(audioGroup, STREAM_PLAYBACK); audioGroup->record_stream = hda_stream_new(audioGroup, STREAM_RECORD); TRACE("hda: streams playback %p, record %p\n", audioGroup->playback_stream, @@ -1295,6 +1294,7 @@ hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID) if (audioGroup->playback_stream != NULL || audioGroup->record_stream != NULL) { codec->audio_groups[codec->num_audio_groups++] = audioGroup; + hda_audio_group_check_sense(audioGroup, false); return B_OK; } @@ -1527,8 +1527,6 @@ hda_codec_new(hda_controller* controller, uint32 codecAddress) } } - hda_codec_check_sense(codec, false); - codec->unsol_response_thread = spawn_kernel_thread( (status_t(*)(void*))hda_codec_switch_handler, "hda_codec_unsol_thread", B_LOW_PRIORITY, codec); From 31e17f9d7b68cac80963bbc2995119cb094965ed Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Wed, 18 Sep 2013 21:50:36 +0200 Subject: [PATCH 120/137] norflash: fix handling of boundaries This was slightly off since my introduction of hidden sectors^^^^^ blocks in the norflash driver. --- src/add-ons/kernel/drivers/disk/norflash/norflash.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp b/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp index 1fd7be7e40..27d371f69a 100644 --- a/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp +++ b/src/add-ons/kernel/drivers/disk/norflash/norflash.cpp @@ -63,6 +63,9 @@ nor_init_device(void *_info, void **_cookie) if (info->id < 0) return info->id; + info->mapped += HIDDEN_BLOCKS * info->blocksize; + + *_cookie = info; return B_OK; } @@ -142,8 +145,6 @@ nor_read(void *_cookie, off_t position, void *data, size_t *numbytes) nor_driver_info *info = (nor_driver_info*)_cookie; TRACE("read(%Ld,%lu)\n", position, *numbytes); - position += HIDDEN_BLOCKS * info->blocksize; - if (position + *numbytes > info->totalsize) *numbytes = info->totalsize - (position + *numbytes); From 1847d8c4860f0b13b4483c88d9c354fa3883f688 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Wed, 18 Sep 2013 21:55:37 +0200 Subject: [PATCH 121/137] ARM: user_memcpy/memset/strlcpy: fix my horrible ARM assembly Turns out I was way to green (and tired) last year to code this properly... now they finally work and the kernel is a lot more stable for it. --- src/system/kernel/arch/arm/arch_asm.S | 54 ++++++++++++++------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/system/kernel/arch/arm/arch_asm.S b/src/system/kernel/arch/arm/arch_asm.S index 50e9508274..6c04401717 100644 --- a/src/system/kernel/arch/arm/arch_asm.S +++ b/src/system/kernel/arch/arm/arch_asm.S @@ -82,27 +82,32 @@ FUNCTION(arm_context_switch): bx lr FUNCTION_END(arm_context_switch) + /* addr_t arm_get_fsr(void); */ FUNCTION(arm_get_fsr): mrc p15, 0, r0, c5, c0, 0 @ get FSR bx lr FUNCTION_END(arm_get_fsr) + /* addr_t arm_get_far(void); */ FUNCTION(arm_get_far): mrc p15, 0, r0, c6, c0, 0 @ get FAR bx lr FUNCTION_END(arm_get_far) + /* addr_t arm_get_fp(void); */ FUNCTION(arm_get_fp): mov r0, fp @ get framepointer bx lr FUNCTION_END(arm_get_fp); + /* status_t arch_cpu_user_memcpy(void *to, const void *from, size_t size, addr_t *faultHandler) */ FUNCTION(arch_cpu_user_memcpy): - stmfd sp!, { r4-r6 } + stmfd sp!, { r4-r6, lr } + ldr r6, [r3] ldr r4, =.L_user_memcpy_error str r4, [r3] /* set fault handler */ @@ -112,33 +117,35 @@ FUNCTION(arch_cpu_user_memcpy): str r5, [r0] add r1, #4 add r0, #4 - sub r4, #1 + subs r4, #1 bne 1b + + ands r4, r2, #3 /* size % 4 */ + beq 3f + 2: - and r4, r2, #3 /* size % 4 */ ldrb r5, [r1] strb r5, [r0] add r1, #1 add r0, #1 - sub r4, #1 + subs r4, #1 bne 2b - +3: str r6, [r3] /* restore fault handler */ mov r0, #0 - ldmfd sp!, { r4-r6 } - bx lr + ldmfd sp!, { r4-r6, pc } .L_user_memcpy_error: str r6, [r3] /* restore fault handler */ mov r0, #-1 - ldmfd sp!, { r4-r6 } - bx lr + ldmfd sp!, { r4-r6, pc } FUNCTION_END(arch_cpu_user_memcpy) /* status_t arch_cpu_user_memset(void *to, char c, size_t count, addr_t *faultHandler) */ FUNCTION(arch_cpu_user_memset): - stmfd sp!, { r4-r5 } + stmfd sp!, { r4-r5, lr } + ldr r5, [r3] ldr r4, =.L_user_memset_error str r4, [r3] @@ -152,33 +159,31 @@ FUNCTION(arch_cpu_user_memset): 1: str r1, [r0] add r0, r0, #4 - sub r4, r4, #1 + subs r4, r4, #1 bne 1b and r4, r2, #3 /* count % 4 */ 2: strb r1, [r0] add r0, r0, #1 - sub r4, r4, #1 + subs r4, r4, #1 bne 2b mov r0, #0 str r5, [r3] - ldmfd sp!, { r4-r5 } - bx lr + ldmfd sp!, { r4-r5, pc } .L_user_memset_error: mov r0, #-1 str r5, [r3] - ldmfd sp!, { r4-r5 } - bx lr + ldmfd sp!, { r4-r5, pc } FUNCTION_END(arch_cpu_user_memset) /* ssize_t arch_cpu_user_strlcpy(void *to, const void *from, size_t size, addr_t *faultHandler) */ FUNCTION(arch_cpu_user_strlcpy): - stmfd sp!, { r4-r6 } + stmfd sp!, { r4-r6, lr } ldr r5, [r3] ldr r4, =.L_user_strlcpy_error str r4, [r3] @@ -187,7 +192,7 @@ FUNCTION(arch_cpu_user_strlcpy): ldrb r4, [r1, r6] strb r4, [r0, r6] add r6, r6, #1 - and r4, #0xff /* done yet? */ + cmp r4, #0 beq 2f cmp r6, r2 /* reached max length? */ blt 1b @@ -195,18 +200,16 @@ FUNCTION(arch_cpu_user_strlcpy): mov r4, #0 strb r4, [r0, r6] - mov r0, r4 /* return B_OK */ + mov r0, r6 /* return length */ str r5, [r3] /* restore fault handler */ - ldmfd sp!, { r4-r6 } - bx lr + ldmfd sp!, { r4-r6, pc } .L_user_strlcpy_error: mov r0, #-1 str r5, [r3] - ldmfd sp!, { r4-r6 } - bx lr + ldmfd sp!, { r4-r6, pc } FUNCTION_END(arch_cpu_user_strlcpy) @@ -242,12 +245,11 @@ FUNCTION(arch_debug_call_with_fault_handler): blx r2 // regular return - ldmfd sp!, { r4, lr } - bx lr + ldmfd sp!, { r4, pc } // fault -- return via longjmp(jumpBuffer, 1) 1: - mov r0, r4 + mov r0, r1 mov r1, #1 bl longjmp FUNCTION_END(arch_debug_call_with_fault_handler) From 124830be8d438d54f587b68408e7fc036c8bd0f4 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Thu, 19 Sep 2013 01:25:44 +0200 Subject: [PATCH 122/137] ARM: FDT: add DTS[I] files for the first couple of targets. Both for the rPI and the Verdex target we now have FDTs. The verdex DTS is homebrew, the pxa DTSIs come from Linux and should be kept in sync. The rPI DTS and Broadcom DTSI come from FreeBSD HEAD, and should ofcourse also be kept in sync. One global new Jam rule has been introduced for handling DTS compilation, aptly named CompileDTS.... More coming! --- build/jam/MainBuildRules | 10 + src/data/dts/bcm2835.dtsi | 468 +++++++++++++++++++++++++++++++++++++ src/data/dts/pxa27x.dtsi | 14 ++ src/data/dts/pxa2xx.dtsi | 135 +++++++++++ src/data/dts/rpi.dts | 381 ++++++++++++++++++++++++++++++ src/data/dts/skeleton.dtsi | 13 ++ src/data/dts/verdex.dts | 41 ++++ 7 files changed, 1062 insertions(+) create mode 100644 src/data/dts/bcm2835.dtsi create mode 100644 src/data/dts/pxa27x.dtsi create mode 100644 src/data/dts/pxa2xx.dtsi create mode 100644 src/data/dts/rpi.dts create mode 100644 src/data/dts/skeleton.dtsi create mode 100644 src/data/dts/verdex.dts diff --git a/build/jam/MainBuildRules b/build/jam/MainBuildRules index e650f9abd2..4a2ed25ec4 100644 --- a/build/jam/MainBuildRules +++ b/build/jam/MainBuildRules @@ -181,6 +181,16 @@ actions AssembleNasm fi } +rule CompileDTS +{ + Depends $(<) : $(>) ; +} + +actions CompileDTS +{ + dtc -O dtb -o $(1) $(2); +} + rule Ld { # Ld : : : ; diff --git a/src/data/dts/bcm2835.dtsi b/src/data/dts/bcm2835.dtsi new file mode 100644 index 0000000000..8078ee413c --- /dev/null +++ b/src/data/dts/bcm2835.dtsi @@ -0,0 +1,468 @@ +/* + * Copyright (c) 2012 Oleksandr Tymoshenko + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + cpu@0 { + compatible = "arm,1176jzf-s"; + }; + }; + + + SOC: axi { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x20000000 0x01000000>; + ranges = <0 0x20000000 0x01000000>; + + intc: interrupt-controller { + compatible = "broadcom,bcm2835-armctrl-ic", + "broadcom,bcm2708-armctrl-ic"; + reg = <0xB200 0x200>; + + interrupt-controller; + #interrupt-cells = <1>; + + /* Bank 0 + * 0: ARM_TIMER + * 1: ARM_MAILBOX + * 2: ARM_DOORBELL_0 + * 3: ARM_DOORBELL_1 + * 4: VPU0_HALTED + * 5: VPU1_HALTED + * 6: ILLEGAL_TYPE0 + * 7: ILLEGAL_TYPE1 + */ + + /* Bank 1 + * 0: TIMER0 16: DMA0 + * 1: TIMER1 17: DMA1 + * 2: TIMER2 18: VC_DMA2 + * 3: TIMER3 19: VC_DMA3 + * 4: CODEC0 20: DMA4 + * 5: CODEC1 21: DMA5 + * 6: CODEC2 22: DMA6 + * 7: VC_JPEG 23: DMA7 + * 8: ISP 24: DMA8 + * 9: VC_USB 25: DMA9 + * 10: VC_3D 26: DMA10 + * 11: TRANSPOSER 27: DMA11 + * 12: MULTICORESYNC0 28: DMA12 + * 13: MULTICORESYNC1 29: AUX + * 14: MULTICORESYNC2 30: ARM + * 15: MULTICORESYNC3 31: VPUDMA + */ + + /* Bank 2 + * 0: HOSTPORT 16: SMI + * 1: VIDEOSCALER 17: GPIO0 + * 2: CCP2TX 18: GPIO1 + * 3: SDC 19: GPIO2 + * 4: DSI0 20: GPIO3 + * 5: AVE 21: VC_I2C + * 6: CAM0 22: VC_SPI + * 7: CAM1 23: VC_I2SPCM + * 8: HDMI0 24: VC_SDIO + * 9: HDMI1 25: VC_UART + * 10: PIXELVALVE1 26: SLIMBUS + * 11: I2CSPISLV 27: VEC + * 12: DSI1 28: CPG + * 13: PWA0 29: RNG + * 14: PWA1 30: VC_ARASANSDIO + * 15: CPR 31: AVSPMON + */ + }; + + timer { + compatible = "broadcom,bcm2835-system-timer", + "broadcom,bcm2708-system-timer"; + reg = <0x3000 0x1000>; + interrupts = <8 9 10 11>; + interrupt-parent = <&intc>; + + clock-frequency = <1000000>; + }; + + armtimer { + /* Not AMBA compatible */ + compatible = "broadcom,bcm2835-sp804", "arm,sp804"; + reg = <0xB400 0x24>; + interrupts = <0>; + interrupt-parent = <&intc>; + }; + + watchdog0 { + compatible = "broadcom,bcm2835-wdt", + "broadcom,bcm2708-wdt"; + reg = <0x10001c 0x0c>; /* 0x1c, 0x20, 0x24 */ + }; + + gpio: gpio { + compatible = "broadcom,bcm2835-gpio", + "broadcom,bcm2708-gpio"; + reg = <0x200000 0xb0>; + + /* Unusual arrangement of interrupts + * (determined by testing) + * 17: Bank 0 (GPIOs 0-31) + * 19: Bank 1 (GPIOs 32-53) + * 18: Bank 2 + * 20: All banks (GPIOs 0-53) + */ + interrupts = <57 59 58 60>; + interrupt-parent = <&intc>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <1>; + + pinctrl-names = "default"; + pinctrl-0 = <&pins_reserved>; + + /* Pins that can short 3.3V to GND in output mode: 46-47 + * Pins used by VideoCore: 48-53 + */ + broadcom,read-only = <46>, <47>, <48>, <49>, <50>, + <51>, <52>, <53>; + + /* BSC0 */ + pins_bsc0_a: bsc0_a { + broadcom,pins = <0>, <1>; + }; + + pins_bsc0_b: bsc0_b { + broadcom,pins = <28>, <29>; + }; + + pins_bsc0_c: bsc0_c { + broadcom,pins = <44>, <45>; + }; + + /* BSC1 */ + pins_bsc1_a: bsc1_a { + broadcom,pins = <2>, <3>; + }; + + pins_bsc1_b: bsc1_b { + broadcom,pins = <44>, <45>; + }; + + /* GPCLK0 */ + pins_gpclk0_a: gpclk0_a { + broadcom,pins = <4>; + }; + + pins_gpclk0_b: gpclk0_b { + broadcom,pins = <20>; + }; + + pins_gpclk0_c: gpclk0_c { + broadcom,pins = <32>; + }; + + pins_gpclk0_d: gpclk0_d { + broadcom,pins = <34>; + }; + + /* GPCLK1 */ + pins_gpclk1_a: gpclk1_a { + broadcom,pins = <5>; + }; + + pins_gpclk1_b: gpclk1_b { + broadcom,pins = <21>; + }; + + pins_gpclk1_c: gpclk1_c { + broadcom,pins = <42>; + }; + + pins_gpclk1_d: gpclk1_d { + broadcom,pins = <44>; + }; + + /* GPCLK2 */ + pins_gpclk2_a: gpclk2_a { + broadcom,pins = <6>; + }; + + pins_gpclk2_b: gpclk2_b { + broadcom,pins = <43>; + }; + + /* SPI0 */ + pins_spi0_a: spi0_a { + broadcom,pins = <7>, <8>, <9>, <10>, <11>; + }; + + pins_spi0_b: spi0_b { + broadcom,pins = <35>, <36>, <37>, <38>, <39>; + }; + + /* PWM */ + pins_pwm0_a: pwm0_a { + broadcom,pins = <12>; + }; + + pins_pwm0_b: pwm0_b { + broadcom,pins = <18>; + }; + + pins_pwm0_c: pwm0_c { + broadcom,pins = <40>; + }; + + pins_pwm1_a: pwm1_a { + broadcom,pins = <13>; + }; + + pins_pwm1_b: pwm1_b { + broadcom,pins = <19>; + }; + + pins_pwm1_c: pwm1_c { + broadcom,pins = <41>; + }; + + pins_pwm1_d: pwm1_d { + broadcom,pins = <45>; + }; + + /* UART0 */ + pins_uart0_a: uart0_a { + broadcom,pins = <14>, <15>; + }; + + pins_uart0_b: uart0_b { + broadcom,pins = <32>, <33>; + }; + + pins_uart0_c: uart0_c { + broadcom,pins = <36>, <37>; + }; + + pins_uart0_fc_a: uart0_fc_a { + broadcom,pins = <16>, <17>; + }; + + pins_uart0_fc_b: uart0_fc_b { + broadcom,pins = <30>, <31>; + }; + + pins_uart0_fc_c: uart0_fc_c { + broadcom,pins = <39>, <38>; + }; + + /* PCM */ + pins_pcm_a: pcm_a { + broadcom,pins = <18>, <19>, <20>, <21>; + }; + + pins_pcm_b: pcm_b { + broadcom,pins = <28>, <29>, <30>, <31>; + }; + + /* Secondary Address Bus */ + pins_sm_addr_a: sm_addr_a { + broadcom,pins = <5>, <4>, <3>, <2>, <1>, <0>; + }; + + pins_sm_addr_b: sm_addr_b { + broadcom,pins = <33>, <32>, <31>, <30>, <29>, + <28>; + }; + + pins_sm_ctl_a: sm_ctl_a { + broadcom,pins = <6>, <7>; + }; + + pins_sm_ctl_b: sm_ctl_b { + broadcom,pins = <34>, <35>; + }; + + pins_sm_data_8bit_a: sm_data_8bit_a { + broadcom,pins = <8>, <9>, <10>, <11>, <12>, + <13>, <14>, <15>; + }; + + pins_sm_data_8bit_b: sm_data_8bit_b { + broadcom,pins = <36>, <37>, <38>, <39>, <40>, + <41>, <42>, <43>; + }; + + pins_sm_data_16bit: sm_data_16bit { + broadcom,pins = <16>, <17>, <18>, <19>, <20>, + <21>, <22>, <23>; + }; + + pins_sm_data_18bit: sm_data_18bit { + broadcom,pins = <24>, <25>; + }; + + /* BSCSL */ + pins_bscsl: bscsl { + broadcom,pins = <18>, <19>; + }; + + /* SPISL */ + pins_spisl: spisl { + broadcom,pins = <18>, <19>, <20>, <21>; + }; + + /* SPI1 */ + pins_spi1: spi1 { + broadcom,pins = <16>, <17>, <18>, <19>, <20>, + <21>; + }; + + /* UART1 */ + pins_uart1_a: uart1_a { + broadcom,pins = <14>, <15>; + }; + + pins_uart1_b: uart1_b { + broadcom,pins = <32>, <33>; + }; + + pins_uart1_c: uart1_c { + broadcom,pins = <40>, <41>; + }; + + pins_uart1_fc_a: uart1_fc_a { + broadcom,pins = <16>, <17>; + }; + + pins_uart1_fc_b: uart1_fc_b { + broadcom,pins = <30>, <31>; + }; + + pins_uart1_fc_c: uart1_fc_c { + broadcom,pins = <43>, <42>; + }; + + /* SPI2 */ + pins_spi2: spi2 { + broadcom,pins = <40>, <41>, <42>, <43>, <44>, + <45>; + }; + + /* ARM JTAG */ + pins_arm_jtag_trst: arm_jtag_trst { + broadcom,pins = <22>; + }; + + pins_arm_jtag_a: arm_jtag_a { + broadcom,pins = <4>, <5>, <6>, <12>, <13>; + }; + + pins_arm_jtag_b: arm_jtag_b { + broadcom,pins = <23>, <24>, <25>, <26>, <27>; + }; + + /* Reserved */ + pins_reserved: reserved { + broadcom,pins = <48>, <49>, <50>, <51>, <52>, + <53>; + }; + }; + + dma: dma { + compatible = "broadcom,bcm2835-dma", + "broadcom,bcm2708-dma"; + reg = <0x7000 0x1000>, <0xE05000 0x1000>; + interrupts = <24 25 26 27 28 29 30 31 32 33 34 35 36>; + interrupt-parent = <&intc>; + + broadcom,channels = <0>; /* Set by VideoCore */ + }; + + vc_mbox: mbox { + compatible = "broadcom,bcm2835-mbox", + "broadcom,bcm2708-mbox"; + reg = <0xB880 0x40>; + interrupts = <1>; + interrupt-parent = <&intc>; + + /* Channels + * 0: Power + * 1: Frame buffer + * 2: Virtual UART + * 3: VCHIQ + * 4: LEDs + * 5: Buttons + * 6: Touch screen + */ + }; + + sdhci { + compatible = "broadcom,bcm2835-sdhci", + "broadcom,bcm2708-sdhci"; + reg = <0x300000 0x100>; + interrupts = <70>; + interrupt-parent = <&intc>; + + clock-frequency = <50000000>; /* Set by VideoCore */ + }; + + uart0: uart0 { + compatible = "broadcom,bcm2835-uart", + "broadcom,bcm2708-uart", "arm,pl011", + "arm,primecell"; + reg = <0x201000 0x1000>; + interrupts = <65>; + interrupt-parent = <&intc>; + + clock-frequency = <3000000>; /* Set by VideoCore */ + reg-shift = <2>; + }; + + vchiq { + compatible = "broadcom,bcm2835-vchiq"; + reg = <0xB800 0x50>; + interrupts = <2>; + interrupt-parent = <&intc>; + }; + + usb { + compatible = "broadcom,bcm2835-usb", + "broadcom,bcm2708-usb", + "synopsys,designware-hs-otg2"; + reg = <0x980000 0x20000>; + interrupts = <17>; + interrupt-parent = <&intc>; + #address-cells = <1>; + #size-cells = <0>; + }; + + }; +}; diff --git a/src/data/dts/pxa27x.dtsi b/src/data/dts/pxa27x.dtsi new file mode 100644 index 0000000000..d7c5d721a5 --- /dev/null +++ b/src/data/dts/pxa27x.dtsi @@ -0,0 +1,14 @@ +/* The pxa3xx skeleton simply augments the 2xx version */ +/include/ "pxa2xx.dtsi" + +/ { + model = "Marvell PXA27x familiy SoC"; + compatible = "marvell,pxa27x"; + + pxabus { + pxairq: interrupt-controller@40d00000 { + marvell,intc-priority; + marvell,intc-nr-irqs = <34>; + }; + }; +}; diff --git a/src/data/dts/pxa2xx.dtsi b/src/data/dts/pxa2xx.dtsi new file mode 100644 index 0000000000..a5e90f078a --- /dev/null +++ b/src/data/dts/pxa2xx.dtsi @@ -0,0 +1,135 @@ +/* + * pxa2xx.dtsi - Device Tree Include file for Marvell PXA2xx family SoC + * + * Copyright (C) 2011 Marek Vasut + * + * Licensed under GPLv2 or later. + */ + +/include/ "skeleton.dtsi" + +/ { + model = "Marvell PXA2xx family SoC"; + compatible = "marvell,pxa2xx"; + interrupt-parent = <&pxairq>; + + aliases { + serial0 = &ffuart; + serial1 = &btuart; + serial2 = &stuart; + serial3 = &hwuart; + i2c0 = &pwri2c; + i2c1 = &pxai2c1; + }; + + cpus { + #address-cells = <0>; + #size-cells = <0>; + cpu { + compatible = "marvell,xscale"; + device_type = "cpu"; + }; + }; + + pxabus { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pxairq: interrupt-controller@40d00000 { + #interrupt-cells = <1>; + compatible = "marvell,pxa-intc"; + interrupt-controller; + interrupt-parent; + marvell,intc-nr-irqs = <32>; + reg = <0x40d00000 0xd0>; + }; + + gpio: gpio@40e00000 { + compatible = "mrvl,pxa-gpio"; + #address-cells = <0x1>; + #size-cells = <0x1>; + reg = <0x40e00000 0x10000>; + gpio-controller; + #gpio-cells = <0x2>; + interrupts = <10>; + interrupt-names = "gpio_mux"; + interrupt-controller; + #interrupt-cells = <0x2>; + ranges; + + gcb0: gpio@40e00000 { + reg = <0x40e00000 0x4>; + }; + + gcb1: gpio@40e00004 { + reg = <0x40e00004 0x4>; + }; + + gcb2: gpio@40e00008 { + reg = <0x40e00008 0x4>; + }; + gcb3: gpio@40e0000c { + reg = <0x40e0000c 0x4>; + }; + }; + + ffuart: uart@40100000 { + compatible = "mrvl,pxa-uart"; + reg = <0x40100000 0x30>; + interrupts = <22>; + status = "disabled"; + }; + + btuart: uart@40200000 { + compatible = "mrvl,pxa-uart"; + reg = <0x40200000 0x30>; + interrupts = <21>; + status = "disabled"; + }; + + stuart: uart@40700000 { + compatible = "mrvl,pxa-uart"; + reg = <0x40700000 0x30>; + interrupts = <20>; + status = "disabled"; + }; + + hwuart: uart@41100000 { + compatible = "mrvl,pxa-uart"; + reg = <0x41100000 0x30>; + interrupts = <7>; + status = "disabled"; + }; + + pxai2c1: i2c@40301680 { + compatible = "mrvl,pxa-i2c"; + reg = <0x40301680 0x30>; + interrupts = <18>; + #address-cells = <0x1>; + #size-cells = <0>; + status = "disabled"; + }; + + usb0: ohci@4c000000 { + compatible = "mrvl,pxa-ohci"; + reg = <0x4c000000 0x10000>; + interrupts = <3>; + status = "disabled"; + }; + + mmc0: mmc@41100000 { + compatible = "mrvl,pxa-mmc"; + reg = <0x41100000 0x1000>; + interrupts = <23>; + status = "disabled"; + }; + + rtc@40900000 { + compatible = "marvell,pxa-rtc"; + reg = <0x40900000 0x3c>; + interrupts = <30 31>; + }; + }; +}; diff --git a/src/data/dts/rpi.dts b/src/data/dts/rpi.dts new file mode 100644 index 0000000000..bdcee00dcb --- /dev/null +++ b/src/data/dts/rpi.dts @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2012 Oleksandr Tymoshenko + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +/dts-v1/; + +/include/ "bcm2835.dtsi" + +/memreserve/ 0x08000000 0x08000000; /* Set by VideoCore */ + +/ { + model = "Raspberry Pi (BCM2835)"; + compatible = "raspberrypi,model-a", "raspberrypi,model-b", + "broadcom,bcm2835-vc", "broadcom,bcm2708-vc"; + + memory { + device_type = "memory"; + reg = <0 0x8000000>; /* 128MB, Set by VideoCore */ + + }; + + system { + revision = <0>; /* Set by VideoCore */ + serial = <0 0>; /* Set by VideoCore */ + }; + + axi { + gpio: gpio { + /* BSC0 */ + pins_bsc0_a: bsc0_a { + broadcom,function = "ALT0"; + }; + + pins_bsc0_b: bsc0_b { + broadcom,function = "ALT0"; + }; + + pins_bsc0_c: bsc0_c { + broadcom,function = "ALT1"; + }; + + /* BSC1 */ + pins_bsc1_a: bsc1_a { + broadcom,function = "ALT0"; + }; + + pins_bsc1_b: bsc1_b { + broadcom,function = "ALT2"; + }; + + /* GPCLK0 */ + pins_gpclk0_a: gpclk0_a { + broadcom,function = "ALT0"; + }; + + pins_gpclk0_b: gpclk0_b { + broadcom,function = "ALT5"; + }; + + pins_gpclk0_c: gpclk0_c { + broadcom,function = "ALT0"; + }; + + pins_gpclk0_d: gpclk0_d { + broadcom,function = "ALT0"; + }; + + /* GPCLK1 */ + pins_gpclk1_a: gpclk1_a { + broadcom,function = "ALT0"; + }; + + pins_gpclk1_b: gpclk1_b { + broadcom,function = "ALT5"; + }; + + pins_gpclk1_c: gpclk1_c { + broadcom,function = "ALT0"; + }; + + pins_gpclk1_d: gpclk1_d { + broadcom,function = "ALT0"; + }; + + /* GPCLK2 */ + pins_gpclk2_a: gpclk2_a { + broadcom,function = "ALT0"; + }; + + pins_gpclk2_b: gpclk2_b { + broadcom,function = "ALT0"; + }; + + /* SPI0 */ + pins_spi0_a: spi0_a { + broadcom,function = "ALT0"; + }; + + pins_spi0_b: spi0_b { + broadcom,function = "ALT0"; + }; + + /* PWM */ + pins_pwm0_a: pwm0_a { + broadcom,function = "ALT0"; + }; + + pins_pwm0_b: pwm0_b { + broadcom,function = "ALT5"; + }; + + pins_pwm0_c: pwm0_c { + broadcom,function = "ALT0"; + }; + + pins_pwm1_a: pwm1_a { + broadcom,function = "ALT0"; + }; + + pins_pwm1_b: pwm1_b { + broadcom,function = "ALT5"; + }; + + pins_pwm1_c: pwm1_c { + broadcom,function = "ALT0"; + }; + + pins_pwm1_d: pwm1_d { + broadcom,function = "ALT0"; + }; + + /* UART0 */ + pins_uart0_a: uart0_a { + broadcom,function = "ALT0"; + }; + + pins_uart0_b: uart0_b { + broadcom,function = "ALT3"; + }; + + pins_uart0_c: uart0_c { + broadcom,function = "ALT2"; + }; + + pins_uart0_fc_a: uart0_fc_a { + broadcom,function = "ALT3"; + }; + + pins_uart0_fc_b: uart0_fc_b { + broadcom,function = "ALT3"; + }; + + pins_uart0_fc_c: uart0_fc_c { + broadcom,function = "ALT2"; + }; + + /* PCM */ + pins_pcm_a: pcm_a { + broadcom,function = "ALT0"; + }; + + pins_pcm_b: pcm_b { + broadcom,function = "ALT2"; + }; + + /* Secondary Address Bus */ + pins_sm_addr_a: sm_addr_a { + broadcom,function = "ALT1"; + }; + + pins_sm_addr_b: sm_addr_b { + broadcom,function = "ALT1"; + }; + + pins_sm_ctl_a: sm_ctl_a { + broadcom,function = "ALT1"; + }; + + pins_sm_ctl_b: sm_ctl_b { + broadcom,function = "ALT1"; + }; + + pins_sm_data_8bit_a: sm_data_8bit_a { + broadcom,function = "ALT1"; + }; + + pins_sm_data_8bit_b: sm_data_8bit_b { + broadcom,function = "ALT1"; + }; + + pins_sm_data_16bit: sm_data_16bit { + broadcom,function = "ALT1"; + }; + + pins_sm_data_18bit: sm_data_18bit { + broadcom,function = "ALT1"; + }; + + /* BSCSL */ + pins_bscsl: bscsl { + broadcom,function = "ALT3"; + }; + + /* SPISL */ + pins_spisl: spisl { + broadcom,function = "ALT3"; + }; + + /* SPI1 */ + pins_spi1: spi1 { + broadcom,function = "ALT4"; + }; + + /* UART1 */ + pins_uart1_a: uart1_a { + broadcom,function = "ALT5"; + }; + + pins_uart1_b: uart1_b { + broadcom,function = "ALT5"; + }; + + pins_uart1_c: uart1_c { + broadcom,function = "ALT5"; + }; + + pins_uart1_fc_a: uart1_fc_a { + broadcom,function = "ALT5"; + }; + + pins_uart1_fc_b: uart1_fc_b { + broadcom,function = "ALT5"; + }; + + pins_uart1_fc_c: uart1_fc_c { + broadcom,function = "ALT5"; + }; + + /* SPI2 */ + pins_spi2: spi2 { + broadcom,function = "ALT4"; + }; + + /* ARM JTAG */ + pins_arm_jtag_trst: arm_jtag_trst { + broadcom,function = "ALT4"; + }; + + pins_arm_jtag_a: arm_jtag_a { + broadcom,function = "ALT5"; + }; + + pins_arm_jtag_b: arm_jtag_b { + broadcom,function = "ALT4"; + }; + + /* Reserved */ + pins_reserved: reserved { + broadcom,function = "ALT3"; + }; + }; + usb { + hub { + compatible = "usb,hub", "usb,device"; + reg = <0x00000001>; + #address-cells = <1>; + #size-cells = <0>; + ethernet { + compatible = "net,ethernet", + "usb,device"; + reg = <0x00000001>; + mac-address = [00 00 00 00 00 00]; + }; + }; + + }; + + + }; + + display { + compatible = "broadcom,bcm2835-fb", "broadcom,bcm2708-fb"; + + broadcom,vc-mailbox = <&vc_mbox>; + broadcom,vc-channel = <1>; + + broadcom,width = <0>; /* Set by VideoCore */ + broadcom,height = <0>; /* Set by VideoCore */ + broadcom,depth = <0>; /* Set by VideoCore */ + }; + + leds { + compatible = "gpio-leds"; + + ok { + label = "ok"; + gpios = <&gpio 16 1>; + + /* Don't change this - it configures + * how the led driver determines if + * the led is on or off when it loads. + */ + default-state = "keep"; + + /* This is the real default state. */ + linux,default-trigger = "default-on"; + }; + }; + + power: regulator { + compatible = "broadcom,bcm2835-power-mgr", + "broadcom,bcm2708-power-mgr", + "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + broadcom,vc-mailbox = <&vc_mbox>; + broadcom,vc-channel = <0>; + + regulator-name = "VideoCore"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on = <1>; + + sd_card_power: regulator@0 { + compatible = "broadcom,bcm2835-power-dev", + "broadcom,bcm2708-power-dev"; + reg = <0>; + + vin-supply = <&power>; + regulator-name = "SD Card"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + /* This is for the controller itself, not the root port */ + usb_hcd_power: regulator@3 { + compatible = "broadcom,bcm2835-power-dev", + "broadcom,bcm2708-power-dev"; + reg = <3>; + + vin-supply = <&power>; + regulator-name = "USB HCD"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + }; + + aliases { + uart0 = &uart0; + }; + + chosen { + bootargs = ""; /* Set by VideoCore */ + stdin = "uart0"; + stdout = "uart0"; + }; + +}; diff --git a/src/data/dts/skeleton.dtsi b/src/data/dts/skeleton.dtsi new file mode 100644 index 0000000000..b41d241de2 --- /dev/null +++ b/src/data/dts/skeleton.dtsi @@ -0,0 +1,13 @@ +/* + * Skeleton device tree; the bare minimum needed to boot; just include and + * add a compatible value. The bootloader will typically populate the memory + * node. + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + chosen { }; + aliases { }; + memory { device_type = "memory"; reg = <0 0>; }; +}; diff --git a/src/data/dts/verdex.dts b/src/data/dts/verdex.dts new file mode 100644 index 0000000000..eaabe757ac --- /dev/null +++ b/src/data/dts/verdex.dts @@ -0,0 +1,41 @@ +/dts-v1/; +/include/ "pxa27x.dtsi" + +/ { + model = "Gumstix Verdex"; + compatible = "gumstix,verdex", "marvell,pxa27x"; + + chosen { + bootargs = "console=ttyS0,115200 debug"; + }; + + memory { + reg = <0xa0000000 0x10000000>; + }; + + pxabus { + ffuart: uart@40100000 { + status = "okay"; + }; + + usb0: ohci@4c000000 { + status = "okay"; + }; + + /* The devices below should be in pxa27x.dtsi, but I kept them here + so to keep the files from upstream as clean as possible for now */ + + lcdc: lcdc@44000000 { + compatible = "mrvl,pxa-lcdc" ; + reg = <0x44000000 0xa0> ; + interrupts = <17> ; + }; + + timers: timers@40a00000 { + compatible = "mrvl,pxa-timers" ; + reg = <0x40a00000 0xc0> ; + interrupts = <26>, <27>, <28>, <29>, <7> ; + interrupt-names = "OST_0", "OST_1", "OST_2", "OST_3", "OST_4_11" ; + }; + }; +}; From e8a2aa0b2841fe26c7bce158ae0196430ce246e7 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Thu, 19 Sep 2013 01:30:12 +0200 Subject: [PATCH 123/137] ARM: FDT: verdex: fix the PXA2xx DTSI file. It references a non-existing device in the aliases, just comment it out until we sort out with upstream what's up. (Since we've also added PXA devices to the Verdex definition we need to chat with them anyway) --- src/data/dts/pxa2xx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/dts/pxa2xx.dtsi b/src/data/dts/pxa2xx.dtsi index a5e90f078a..670e23090b 100644 --- a/src/data/dts/pxa2xx.dtsi +++ b/src/data/dts/pxa2xx.dtsi @@ -18,7 +18,7 @@ serial1 = &btuart; serial2 = &stuart; serial3 = &hwuart; - i2c0 = &pwri2c; + /* i2c0 = &pwri2c; */ i2c1 = &pxai2c1; }; From e7c330c6f3d36d1ccb98be6f0eb4bae1ff9be160 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Thu, 19 Sep 2013 03:15:06 +0200 Subject: [PATCH 124/137] ARM: improve error output, fix iframe reporting. --- src/system/kernel/arch/arm/arch_int.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/system/kernel/arch/arm/arch_int.cpp b/src/system/kernel/arch/arm/arch_int.cpp index 0dc4fdcd9f..25aad9e0cf 100644 --- a/src/system/kernel/arch/arm/arch_int.cpp +++ b/src/system/kernel/arch/arm/arch_int.cpp @@ -31,7 +31,7 @@ #include -//#define TRACE_ARCH_INT +#define TRACE_ARCH_INT #ifdef TRACE_ARCH_INT # define TRACE(x) dprintf x #else @@ -108,9 +108,9 @@ print_iframe(const char *event, struct iframe *frame) frame->r0, frame->r1, frame->r2, frame->r3, frame->r4, frame->r5, frame->r6, frame->r7); dprintf("R08=%08lx R09=%08lx R10=%08lx R11=%08lx\n" - "R12=%08lx R13=%08lx R14=%08lx CPSR=%08lx\n", + "R12=%08lx SP=%08lx LR=%08lx PC=%08lx CPSR=%08lx\n", frame->r8, frame->r9, frame->r10, frame->r11, - frame->r12, frame->usr_sp, frame->usr_lr, frame->spsr); + frame->r12, frame->svc_sp, frame->svc_lr, frame->pc, frame->spsr); } @@ -215,9 +215,9 @@ private: extern "C" void arch_arm_undefined(struct iframe *iframe) { + print_iframe("Undefined Instruction", iframe); IFrameScope scope(iframe); // push/pop iframe - print_iframe("Undefined Instruction", iframe); panic("not handled!"); } @@ -225,17 +225,14 @@ arch_arm_undefined(struct iframe *iframe) extern "C" void arch_arm_syscall(struct iframe *iframe) { - IFrameScope scope(iframe); // push/pop iframe - print_iframe("Software interrupt", iframe); + IFrameScope scope(iframe); // push/pop iframe } extern "C" void arch_arm_data_abort(struct iframe *frame) { - IFrameScope scope(iframe); - Thread *thread = thread_get_current_thread(); bool isUser = (frame->spsr & 0x1f) == 0x10; addr_t far = arm_get_far(); @@ -244,8 +241,11 @@ arch_arm_data_abort(struct iframe *frame) #ifdef TRACE_ARCH_INT print_iframe("Data Abort", frame); + dprintf("FAR: %08lx, thread: %s\n", far, thread->name); #endif + IFrameScope scope(frame); + if (debug_debugger_running()) { // If this CPU or this thread has a fault handler, we're allowed to be // here. @@ -320,9 +320,9 @@ arch_arm_data_abort(struct iframe *frame) extern "C" void arch_arm_prefetch_abort(struct iframe *iframe) { + print_iframe("Prefetch Abort", iframe); IFrameScope scope(iframe); - print_iframe("Prefetch Abort", iframe); panic("not handled!"); } From 09c9f21ce48c1af30ab4c54ea77687e5fe62fd19 Mon Sep 17 00:00:00 2001 From: John Scipione Date: Thu, 19 Sep 2013 19:03:38 -0400 Subject: [PATCH 125/137] ScreenSaver: tabs hug window boundary Taking a page from HaikuDepot's book, remove the border from the tab view and set the inset to 0 in order to position the tabview right on the window's edge. Looks a bit better than the previous method since the tabview border appeared to extend the thickness of the window border. --- src/preferences/screensaver/ScreenSaverWindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/preferences/screensaver/ScreenSaverWindow.cpp b/src/preferences/screensaver/ScreenSaverWindow.cpp index 4d4303cc1a..7822bfe156 100644 --- a/src/preferences/screensaver/ScreenSaverWindow.cpp +++ b/src/preferences/screensaver/ScreenSaverWindow.cpp @@ -861,6 +861,7 @@ ScreenSaverWindow::ScreenSaverWindow() // Create the tab view fTabView = new BTabView("tab_view", B_WIDTH_FROM_LABEL); + fTabView->SetBorder(B_NO_BORDER); // Create the controls inside the tabs fFadeView = new FadeView(B_TRANSLATE("General"), fSettings); @@ -876,7 +877,7 @@ ScreenSaverWindow::ScreenSaverWindow() B_ALIGN_USE_FULL_HEIGHT)); topView->SetExplicitMinSize(BSize(fMinWidth, fMinHeight)); BLayoutBuilder::Group<>(topView, B_VERTICAL) - .SetInsets(-1, B_USE_SMALL_SPACING, -1, -1) + .SetInsets(0, B_USE_SMALL_SPACING, 0, 0) .Add(fTabView) .End(); From 8304a88369112130df483f4752bb9e82985f8b74 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Fri, 20 Sep 2013 15:41:30 -0500 Subject: [PATCH 126/137] radeon_hd: Add PCIID for another REDWOOD card. * Resovles #9993 --- src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp b/src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp index e948edc4c2..9a5ef903d1 100644 --- a/src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp @@ -173,6 +173,7 @@ const struct supported_device { // Redwood {0x68da, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5500"}, {0x68d9, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5570"}, + {0x675f, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5570"}, {0x68b9, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5600"}, {0x68c1, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5650"}, {0x68d8, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5670"}, From 3ffd22ce6d0671c4d51507f8b57a78143d9b2ab0 Mon Sep 17 00:00:00 2001 From: Jerome Duval Date: Fri, 20 Sep 2013 23:48:23 +0200 Subject: [PATCH 127/137] usb_disk: base the error sense handling on a reference table. * imported asc-num.txt as a reference, was used to generate the asc sense table. * use the sense asc and key tables to know which action and status codes are to be applied. * tested with an hard disk and a dvd reader. * these tables could be reused by the scsi_periph module. --- docs/develop/kernel/scsi_asc-num-20130919.txt | 728 ++++++++++++++++ headers/private/drivers/scsi_sense.h | 800 ++++++++++++++++++ .../kernel/drivers/disk/usb/usb_disk/Jamfile | 2 +- .../drivers/disk/usb/usb_disk/usb_disk.cpp | 123 +-- 4 files changed, 1593 insertions(+), 60 deletions(-) create mode 100644 docs/develop/kernel/scsi_asc-num-20130919.txt create mode 100644 headers/private/drivers/scsi_sense.h diff --git a/docs/develop/kernel/scsi_asc-num-20130919.txt b/docs/develop/kernel/scsi_asc-num-20130919.txt new file mode 100644 index 0000000000..72cc30a072 --- /dev/null +++ b/docs/develop/kernel/scsi_asc-num-20130919.txt @@ -0,0 +1,728 @@ +File: ASC-NUM.TXT + +SCSI ASC/ASCQ Assignments +Numeric Sorted Listing +as of 9/19/13 + + D - DIRECT ACCESS DEVICE (SBC-3) device column key + .T - SEQUENTIAL ACCESS DEVICE (SSC-3) ------------------- + . L - PRINTER DEVICE (SSC) blank = reserved + . P - PROCESSOR DEVICE (SPC-2) not blank = allowed + . .W - WRITE ONCE READ MULTIPLE DEVICE (SBC) + . . R - C/DVD DEVICE (MMC-6) + . . O - OPTICAL MEMORY DEVICE (SBC) + . . .M - MEDIA CHANGER DEVICE (SMC-3) + . . . A - STORAGE ARRAY DEVICE (SCC-2) + . . . E - ENCLOSURE SERVICES DEVICE (SES-2) + . . . .B - SIMPLIFIED DIRECT-ACCESS DEVICE (RBC) + . . . . K - OPTICAL CARD READER/WRITER DEVICE (OCRW) + . . . . V - AUTOMATION/DRIVE INTERFACE (ADC-2) + . . . . .F - OBJECT-BASED STORAGE (OSD-2) +ASC/ASCQ DTLPWROMAEBKVF Description +------- -------------- ---------------------------------------------------- +00h/00h DTLPWROMAEBKVF NO ADDITIONAL SENSE INFORMATION +00h/01h T FILEMARK DETECTED +00h/02h T END-OF-PARTITION/MEDIUM DETECTED +00h/03h T SETMARK DETECTED +00h/04h T BEGINNING-OF-PARTITION/MEDIUM DETECTED +00h/05h TL END-OF-DATA DETECTED +00h/06h DTLPWROMAEBKVF I/O PROCESS TERMINATED +00h/07h T PROGRAMMABLE EARLY WARNING DETECTED +00h/11h R AUDIO PLAY OPERATION IN PROGRESS +00h/12h R AUDIO PLAY OPERATION PAUSED +00h/13h R AUDIO PLAY OPERATION SUCCESSFULLY COMPLETED +00h/14h R AUDIO PLAY OPERATION STOPPED DUE TO ERROR +00h/15h R NO CURRENT AUDIO STATUS TO RETURN +00h/16h DTLPWROMAEBKVF OPERATION IN PROGRESS +00h/17h DTL WROMAEBKVF CLEANING REQUESTED +00h/18h T ERASE OPERATION IN PROGRESS +00h/19h T LOCATE OPERATION IN PROGRESS +00h/1Ah T REWIND OPERATION IN PROGRESS +00h/1Bh T SET CAPACITY OPERATION IN PROGRESS +00h/1Ch T VERIFY OPERATION IN PROGRESS +00h/1Dh DT B ATA PASS THROUGH INFORMATION AVAILABLE +00h/1Eh DT R MAEBKV CONFLICTING SA CREATION REQUEST +00h/1Fh DT B LOGICAL UNIT TRANSITIONING TO ANOTHER POWER CONDITION +00h/20h DT P B EXTENDED COPY INFORMATION AVAILABLE +01h/00h D W O BK NO INDEX/SECTOR SIGNAL +02h/00h D WRO BK NO SEEK COMPLETE +03h/00h DTL W O BK PERIPHERAL DEVICE WRITE FAULT +03h/01h T NO WRITE CURRENT +03h/02h T EXCESSIVE WRITE ERRORS +04h/00h DTLPWROMAEBKVF LOGICAL UNIT NOT READY, CAUSE NOT REPORTABLE +04h/01h DTLPWROMAEBKVF LOGICAL UNIT IS IN PROCESS OF BECOMING READY +04h/02h DTLPWROMAEBKVF LOGICAL UNIT NOT READY, INITIALIZING COMMAND REQUIRED +04h/03h DTLPWROMAEBKVF LOGICAL UNIT NOT READY, MANUAL INTERVENTION REQUIRED +04h/04h DTL RO B LOGICAL UNIT NOT READY, FORMAT IN PROGRESS +04h/05h DT W O A BK F LOGICAL UNIT NOT READY, REBUILD IN PROGRESS +04h/06h DT W O A BK LOGICAL UNIT NOT READY, RECALCULATION IN PROGRESS +04h/07h DTLPWROMAEBKVF LOGICAL UNIT NOT READY, OPERATION IN PROGRESS +04h/08h R LOGICAL UNIT NOT READY, LONG WRITE IN PROGRESS +04h/09h DTLPWROMAEBKVF LOGICAL UNIT NOT READY, SELF-TEST IN PROGRESS +04h/0Ah DTLPWROMAEBKVF LOGICAL UNIT NOT ACCESSIBLE, ASYMMETRIC ACCESS STATE TRANSITION +04h/0Bh DTLPWROMAEBKVF LOGICAL UNIT NOT ACCESSIBLE, TARGET PORT IN STANDBY STATE +04h/0Ch DTLPWROMAEBKVF LOGICAL UNIT NOT ACCESSIBLE, TARGET PORT IN UNAVAILABLE STATE +04h/0Dh F LOGICAL UNIT NOT READY, STRUCTURE CHECK REQUIRED +04h/10h DT WROM B LOGICAL UNIT NOT READY, AUXILIARY MEMORY NOT ACCESSIBLE +04h/11h DT WRO AEB VF LOGICAL UNIT NOT READY, NOTIFY (ENABLE SPINUP) REQUIRED +04h/12h M V LOGICAL UNIT NOT READY, OFFLINE +04h/13h DT R MAEBKV LOGICAL UNIT NOT READY, SA CREATION IN PROGRESS +04h/14h D B LOGICAL UNIT NOT READY, SPACE ALLOCATION IN PROGRESS +04h/15h M LOGICAL UNIT NOT READY, ROBOTICS DISABLED +04h/16h M LOGICAL UNIT NOT READY, CONFIGURATION REQUIRED +04h/17h M LOGICAL UNIT NOT READY, CALIBRATION REQUIRED +04h/18h M LOGICAL UNIT NOT READY, A DOOR IS OPEN +04h/19h M LOGICAL UNIT NOT READY, OPERATING IN SEQUENTIAL MODE +04h/1Ah D B LOGICAL UNIT NOT READY, START STOP UNIT COMMAND IN PROGRESS +04h/1Bh D B LOGICAL UNIT NOT READY, SANITIZE IN PROGRESS +04h/1Ch DT MAEB LOGICAL UNIT NOT READY, ADDITIONAL POWER USE NOT YET GRANTED +04h/1Dh D LOGICAL UNIT NOT READY, CONFIGURATION IN PROGRESS +04h/1Eh D LOGICAL UNIT NOT READY, MICROCODE ACTIVATION REQUIRED +05h/00h DTL WROMAEBKVF LOGICAL UNIT DOES NOT RESPOND TO SELECTION +06h/00h D WROM BK NO REFERENCE POSITION FOUND +07h/00h DTL WROM BK MULTIPLE PERIPHERAL DEVICES SELECTED +08h/00h DTL WROMAEBKVF LOGICAL UNIT COMMUNICATION FAILURE +08h/01h DTL WROMAEBKVF LOGICAL UNIT COMMUNICATION TIME-OUT +08h/02h DTL WROMAEBKVF LOGICAL UNIT COMMUNICATION PARITY ERROR +08h/03h DT ROM BK LOGICAL UNIT COMMUNICATION CRC ERROR (ULTRA-DMA/32) +08h/04h DTLPWRO K UNREACHABLE COPY TARGET +09h/00h DT WRO B TRACK FOLLOWING ERROR +09h/01h WRO K TRACKING SERVO FAILURE +09h/02h WRO K FOCUS SERVO FAILURE +09h/03h WRO SPINDLE SERVO FAILURE +09h/04h DT WRO B HEAD SELECT FAULT +0Ah/00h DTLPWROMAEBKVF ERROR LOG OVERFLOW +0Bh/00h DTLPWROMAEBKVF WARNING +0Bh/01h DTLPWROMAEBKVF WARNING - SPECIFIED TEMPERATURE EXCEEDED +0Bh/02h DTLPWROMAEBKVF WARNING - ENCLOSURE DEGRADED +0Bh/03h DTLPWROMAEBKVF WARNING - BACKGROUND SELF-TEST FAILED +0Bh/04h DTLPWRO AEBKVF WARNING - BACKGROUND PRE-SCAN DETECTED MEDIUM ERROR +0Bh/05h DTLPWRO AEBKVF WARNING - BACKGROUND MEDIUM SCAN DETECTED MEDIUM ERROR +0Bh/06h DTLPWROMAEBKVF WARNING - NON-VOLATILE CACHE NOW VOLATILE +0Bh/07h DTLPWROMAEBKVF WARNING - DEGRADED POWER TO NON-VOLATILE CACHE +0Bh/08h DTLPWROMAEBKVF WARNING - POWER LOSS EXPECTED +0Bh/09h D WARNING - DEVICE STATISTICS NOTIFICATION ACTIVE +0Ch/00h T R WRITE ERROR +0Ch/01h K WRITE ERROR - RECOVERED WITH AUTO REALLOCATION +0Ch/02h D W O BK WRITE ERROR - AUTO REALLOCATION FAILED +0Ch/03h D W O BK WRITE ERROR - RECOMMEND REASSIGNMENT +0Ch/04h DT W O B COMPRESSION CHECK MISCOMPARE ERROR +0Ch/05h DT W O B DATA EXPANSION OCCURRED DURING COMPRESSION +0Ch/06h DT W O B BLOCK NOT COMPRESSIBLE +0Ch/07h R WRITE ERROR - RECOVERY NEEDED +0Ch/08h R WRITE ERROR - RECOVERY FAILED +0Ch/09h R WRITE ERROR - LOSS OF STREAMING +0Ch/0Ah R WRITE ERROR - PADDING BLOCKS ADDED +0Ch/0Bh DT WROM B AUXILIARY MEMORY WRITE ERROR +0Ch/0Ch DTLPWRO AEBKVF WRITE ERROR - UNEXPECTED UNSOLICITED DATA +0Ch/0Dh DTLPWRO AEBKVF WRITE ERROR - NOT ENOUGH UNSOLICITED DATA +0Ch/0Eh DT W O BK MULTIPLE WRITE ERRORS +0Ch/0Fh R DEFECTS IN ERROR WINDOW +0Dh/00h DTLPWRO A K ERROR DETECTED BY THIRD PARTY TEMPORARY INITIATOR +0Dh/01h DTLPWRO A K THIRD PARTY DEVICE FAILURE +0Dh/02h DTLPWRO A K COPY TARGET DEVICE NOT REACHABLE +0Dh/03h DTLPWRO A K INCORRECT COPY TARGET DEVICE TYPE +0Dh/04h DTLPWRO A K COPY TARGET DEVICE DATA UNDERRUN +0Dh/05h DTLPWRO A K COPY TARGET DEVICE DATA OVERRUN +0Eh/00h DT PWROMAEBK F INVALID INFORMATION UNIT +0Eh/01h DT PWROMAEBK F INFORMATION UNIT TOO SHORT +0Eh/02h DT PWROMAEBK F INFORMATION UNIT TOO LONG +0Eh/03h DT P R MAEBK F INVALID FIELD IN COMMAND INFORMATION UNIT +0Fh/00h +10h/00h D W O BK ID CRC OR ECC ERROR +10h/01h DT W O LOGICAL BLOCK GUARD CHECK FAILED +10h/02h DT W O LOGICAL BLOCK APPLICATION TAG CHECK FAILED +10h/03h DT W O LOGICAL BLOCK REFERENCE TAG CHECK FAILED +10h/04h T LOGICAL BLOCK PROTECTION ERROR ON RECOVER BUFFERED DATA +10h/05h T LOGICAL BLOCK PROTECTION METHOD ERROR +11h/00h DT WRO BK UNRECOVERED READ ERROR +11h/01h DT WRO BK READ RETRIES EXHAUSTED +11h/02h DT WRO BK ERROR TOO LONG TO CORRECT +11h/03h DT W O BK MULTIPLE READ ERRORS +11h/04h D W O BK UNRECOVERED READ ERROR - AUTO REALLOCATE FAILED +11h/05h WRO B L-EC UNCORRECTABLE ERROR +11h/06h WRO B CIRC UNRECOVERED ERROR +11h/07h W O B DATA RE-SYNCHRONIZATION ERROR +11h/08h T INCOMPLETE BLOCK READ +11h/09h T NO GAP FOUND +11h/0Ah DT O BK MISCORRECTED ERROR +11h/0Bh D W O BK UNRECOVERED READ ERROR - RECOMMEND REASSIGNMENT +11h/0Ch D W O BK UNRECOVERED READ ERROR - RECOMMEND REWRITE THE DATA +11h/0Dh DT WRO B DE-COMPRESSION CRC ERROR +11h/0Eh DT WRO B CANNOT DECOMPRESS USING DECLARED ALGORITHM +11h/0Fh R ERROR READING UPC/EAN NUMBER +11h/10h R ERROR READING ISRC NUMBER +11h/11h R READ ERROR - LOSS OF STREAMING +11h/12h DT WROM B AUXILIARY MEMORY READ ERROR +11h/13h DTLPWRO AEBKVF READ ERROR - FAILED RETRANSMISSION REQUEST +11h/14h D READ ERROR - LBA MARKED BAD BY APPLICATION CLIENT +11h/15h D WRITE AFTER SANITIZE REQUIRED +12h/00h D W O BK ADDRESS MARK NOT FOUND FOR ID FIELD +13h/00h D W O BK ADDRESS MARK NOT FOUND FOR DATA FIELD +14h/00h DTL WRO BK RECORDED ENTITY NOT FOUND +14h/01h DT WRO BK RECORD NOT FOUND +14h/02h T FILEMARK OR SETMARK NOT FOUND +14h/03h T END-OF-DATA NOT FOUND +14h/04h T BLOCK SEQUENCE ERROR +14h/05h DT W O BK RECORD NOT FOUND - RECOMMEND REASSIGNMENT +14h/06h DT W O BK RECORD NOT FOUND - DATA AUTO-REALLOCATED +14h/07h T LOCATE OPERATION FAILURE +15h/00h DTL WROM BK RANDOM POSITIONING ERROR +15h/01h DTL WROM BK MECHANICAL POSITIONING ERROR +15h/02h DT WRO BK POSITIONING ERROR DETECTED BY READ OF MEDIUM +16h/00h D W O BK DATA SYNCHRONIZATION MARK ERROR +16h/01h D W O BK DATA SYNC ERROR - DATA REWRITTEN +16h/02h D W O BK DATA SYNC ERROR - RECOMMEND REWRITE +16h/03h D W O BK DATA SYNC ERROR - DATA AUTO-REALLOCATED +16h/04h D W O BK DATA SYNC ERROR - RECOMMEND REASSIGNMENT +17h/00h DT WRO BK RECOVERED DATA WITH NO ERROR CORRECTION APPLIED +17h/01h DT WRO BK RECOVERED DATA WITH RETRIES +17h/02h DT WRO BK RECOVERED DATA WITH POSITIVE HEAD OFFSET +17h/03h DT WRO BK RECOVERED DATA WITH NEGATIVE HEAD OFFSET +17h/04h WRO B RECOVERED DATA WITH RETRIES AND/OR CIRC APPLIED +17h/05h D WRO BK RECOVERED DATA USING PREVIOUS SECTOR ID +17h/06h D W O BK RECOVERED DATA WITHOUT ECC - DATA AUTO-REALLOCATED +17h/07h D WRO BK RECOVERED DATA WITHOUT ECC - RECOMMEND REASSIGNMENT +17h/08h D WRO BK RECOVERED DATA WITHOUT ECC - RECOMMEND REWRITE +17h/09h D WRO BK RECOVERED DATA WITHOUT ECC - DATA REWRITTEN +18h/00h DT WRO BK RECOVERED DATA WITH ERROR CORRECTION APPLIED +18h/01h D WRO BK RECOVERED DATA WITH ERROR CORR. & RETRIES APPLIED +18h/02h D WRO BK RECOVERED DATA - DATA AUTO-REALLOCATED +18h/03h R RECOVERED DATA WITH CIRC +18h/04h R RECOVERED DATA WITH L-EC +18h/05h D WRO BK RECOVERED DATA - RECOMMEND REASSIGNMENT +18h/06h D WRO BK RECOVERED DATA - RECOMMEND REWRITE +18h/07h D W O BK RECOVERED DATA WITH ECC - DATA REWRITTEN +18h/08h R RECOVERED DATA WITH LINKING +19h/00h D O K DEFECT LIST ERROR +19h/01h D O K DEFECT LIST NOT AVAILABLE +19h/02h D O K DEFECT LIST ERROR IN PRIMARY LIST +19h/03h D O K DEFECT LIST ERROR IN GROWN LIST +1Ah/00h DTLPWROMAEBKVF PARAMETER LIST LENGTH ERROR +1Bh/00h DTLPWROMAEBKVF SYNCHRONOUS DATA TRANSFER ERROR +1Ch/00h D O BK DEFECT LIST NOT FOUND +1Ch/01h D O BK PRIMARY DEFECT LIST NOT FOUND +1Ch/02h D O BK GROWN DEFECT LIST NOT FOUND +1Dh/00h DT WRO BK MISCOMPARE DURING VERIFY OPERATION +1Dh/01h D B MISCOMPARE VERIFY OF UNMAPPED LBA +1Eh/00h D W O BK RECOVERED ID WITH ECC CORRECTION +1Fh/00h D O K PARTIAL DEFECT LIST TRANSFER +20h/00h DTLPWROMAEBKVF INVALID COMMAND OPERATION CODE +20h/01h DT PWROMAEBK ACCESS DENIED - INITIATOR PENDING-ENROLLED +20h/02h DT PWROMAEBK ACCESS DENIED - NO ACCESS RIGHTS +20h/03h DT PWROMAEBK ACCESS DENIED - INVALID MGMT ID KEY +20h/04h T ILLEGAL COMMAND WHILE IN WRITE CAPABLE STATE +20h/05h T Obsolete +20h/06h T ILLEGAL COMMAND WHILE IN EXPLICIT ADDRESS MODE +20h/07h T ILLEGAL COMMAND WHILE IN IMPLICIT ADDRESS MODE +20h/08h DT PWROMAEBK ACCESS DENIED - ENROLLMENT CONFLICT +20h/09h DT PWROMAEBK ACCESS DENIED - INVALID LU IDENTIFIER +20h/0Ah DT PWROMAEBK ACCESS DENIED - INVALID PROXY TOKEN +20h/0Bh DT PWROMAEBK ACCESS DENIED - ACL LUN CONFLICT +20h/0Ch T ILLEGAL COMMAND WHEN NOT IN APPEND-ONLY MODE +21h/00h DT WRO BK LOGICAL BLOCK ADDRESS OUT OF RANGE +21h/01h DT WROM BK INVALID ELEMENT ADDRESS +21h/02h R INVALID ADDRESS FOR WRITE +21h/03h R INVALID WRITE CROSSING LAYER JUMP +22h/00h D ILLEGAL FUNCTION (USE 20 00, 24 00, OR 26 00) +23h/00h DT P B INVALID TOKEN OPERATION, CAUSE NOT REPORTABLE +23h/01h DT P B INVALID TOKEN OPERATION, UNSUPPORTED TOKEN TYPE +23h/02h DT P B INVALID TOKEN OPERATION, REMOTE TOKEN USAGE NOT SUPPORTED +23h/03h DT P B INVALID TOKEN OPERATION, REMOTE ROD TOKEN CREATION NOT SUPPORTED +23h/04h DT P B INVALID TOKEN OPERATION, TOKEN UNKNOWN +23h/05h DT P B INVALID TOKEN OPERATION, TOKEN CORRUPT +23h/06h DT P B INVALID TOKEN OPERATION, TOKEN REVOKED +23h/07h DT P B INVALID TOKEN OPERATION, TOKEN EXPIRED +23h/08h DT P B INVALID TOKEN OPERATION, TOKEN CANCELLED +23h/09h DT P B INVALID TOKEN OPERATION, TOKEN DELETED +23h/0Ah DT P B INVALID TOKEN OPERATION, INVALID TOKEN LENGTH +24h/00h DTLPWROMAEBKVF INVALID FIELD IN CDB +24h/01h DTLPWRO AEBKVF CDB DECRYPTION ERROR +24h/02h T Obsolete +24h/03h T Obsolete +24h/04h F SECURITY AUDIT VALUE FROZEN +24h/05h F SECURITY WORKING KEY FROZEN +24h/06h F NONCE NOT UNIQUE +24h/07h F NONCE TIMESTAMP OUT OF RANGE +24h/08h DT R MAEBKV INVALID XCDB +25h/00h DTLPWROMAEBKVF LOGICAL UNIT NOT SUPPORTED +26h/00h DTLPWROMAEBKVF INVALID FIELD IN PARAMETER LIST +26h/01h DTLPWROMAEBKVF PARAMETER NOT SUPPORTED +26h/02h DTLPWROMAEBKVF PARAMETER VALUE INVALID +26h/03h DTLPWROMAE K THRESHOLD PARAMETERS NOT SUPPORTED +26h/04h DTLPWROMAEBKVF INVALID RELEASE OF PERSISTENT RESERVATION +26h/05h DTLPWRO A BK DATA DECRYPTION ERROR +26h/06h DTLPWRO K TOO MANY TARGET DESCRIPTORS +26h/07h DTLPWRO K UNSUPPORTED TARGET DESCRIPTOR TYPE CODE +26h/08h DTLPWRO K TOO MANY SEGMENT DESCRIPTORS +26h/09h DTLPWRO K UNSUPPORTED SEGMENT DESCRIPTOR TYPE CODE +26h/0Ah DTLPWRO K UNEXPECTED INEXACT SEGMENT +26h/0Bh DTLPWRO K INLINE DATA LENGTH EXCEEDED +26h/0Ch DTLPWRO K INVALID OPERATION FOR COPY SOURCE OR DESTINATION +26h/0Dh DTLPWRO K COPY SEGMENT GRANULARITY VIOLATION +26h/0Eh DT PWROMAEBK INVALID PARAMETER WHILE PORT IS ENABLED +26h/0Fh F INVALID DATA-OUT BUFFER INTEGRITY CHECK VALUE +26h/10h T DATA DECRYPTION KEY FAIL LIMIT REACHED +26h/11h T INCOMPLETE KEY-ASSOCIATED DATA SET +26h/12h T VENDOR SPECIFIC KEY REFERENCE NOT FOUND +27h/00h DT WRO BK WRITE PROTECTED +27h/01h DT WRO BK HARDWARE WRITE PROTECTED +27h/02h DT WRO BK LOGICAL UNIT SOFTWARE WRITE PROTECTED +27h/03h T R ASSOCIATED WRITE PROTECT +27h/04h T R PERSISTENT WRITE PROTECT +27h/05h T R PERMANENT WRITE PROTECT +27h/06h R F CONDITIONAL WRITE PROTECT +27h/07h D B SPACE ALLOCATION FAILED WRITE PROTECT +28h/00h DTLPWROMAEBKVF NOT READY TO READY CHANGE, MEDIUM MAY HAVE CHANGED +28h/01h DT WROM B IMPORT OR EXPORT ELEMENT ACCESSED +28h/02h R FORMAT-LAYER MAY HAVE CHANGED +28h/03h M IMPORT/EXPORT ELEMENT ACCESSED, MEDIUM CHANGED +29h/00h DTLPWROMAEBKVF POWER ON, RESET, OR BUS DEVICE RESET OCCURRED +29h/01h DTLPWROMAEBKVF POWER ON OCCURRED +29h/02h DTLPWROMAEBKVF SCSI BUS RESET OCCURRED +29h/03h DTLPWROMAEBKVF BUS DEVICE RESET FUNCTION OCCURRED +29h/04h DTLPWROMAEBKVF DEVICE INTERNAL RESET +29h/05h DTLPWROMAEBKVF TRANSCEIVER MODE CHANGED TO SINGLE-ENDED +29h/06h DTLPWROMAEBKVF TRANSCEIVER MODE CHANGED TO LVD +29h/07h DTLPWROMAEBKVF I_T NEXUS LOSS OCCURRED +2Ah/00h DTL WROMAEBKVF PARAMETERS CHANGED +2Ah/01h DTL WROMAEBKVF MODE PARAMETERS CHANGED +2Ah/02h DTL WROMAE K LOG PARAMETERS CHANGED +2Ah/03h DTLPWROMAE K RESERVATIONS PREEMPTED +2Ah/04h DTLPWROMAE RESERVATIONS RELEASED +2Ah/05h DTLPWROMAE REGISTRATIONS PREEMPTED +2Ah/06h DTLPWROMAEBKVF ASYMMETRIC ACCESS STATE CHANGED +2Ah/07h DTLPWROMAEBKVF IMPLICIT ASYMMETRIC ACCESS STATE TRANSITION FAILED +2Ah/08h DT WROMAEBKVF PRIORITY CHANGED +2Ah/09h D CAPACITY DATA HAS CHANGED +2Ah/0Ah DT ERROR HISTORY I_T NEXUS CLEARED +2Ah/0Bh DT ERROR HISTORY SNAPSHOT RELEASED +2Ah/0Ch F ERROR RECOVERY ATTRIBUTES HAVE CHANGED +2Ah/0Dh T DATA ENCRYPTION CAPABILITIES CHANGED +2Ah/10h DT M E V TIMESTAMP CHANGED +2Ah/11h T DATA ENCRYPTION PARAMETERS CHANGED BY ANOTHER I_T NEXUS +2Ah/12h T DATA ENCRYPTION PARAMETERS CHANGED BY VENDOR SPECIFIC EVENT +2Ah/13h T DATA ENCRYPTION KEY INSTANCE COUNTER HAS CHANGED +2Ah/14h DT R MAEBKV SA CREATION CAPABILITIES DATA HAS CHANGED +2Ah/15h T M V MEDIUM REMOVAL PREVENTION PREEMPTED +2Bh/00h DTLPWRO K COPY CANNOT EXECUTE SINCE HOST CANNOT DISCONNECT +2Ch/00h DTLPWROMAEBKVF COMMAND SEQUENCE ERROR +2Ch/01h TOO MANY WINDOWS SPECIFIED +2Ch/02h INVALID COMBINATION OF WINDOWS SPECIFIED +2Ch/03h R CURRENT PROGRAM AREA IS NOT EMPTY +2Ch/04h R CURRENT PROGRAM AREA IS EMPTY +2Ch/05h B ILLEGAL POWER CONDITION REQUEST +2Ch/06h R PERSISTENT PREVENT CONFLICT +2Ch/07h DTLPWROMAEBKVF PREVIOUS BUSY STATUS +2Ch/08h DTLPWROMAEBKVF PREVIOUS TASK SET FULL STATUS +2Ch/09h DTLPWROM EBKVF PREVIOUS RESERVATION CONFLICT STATUS +2Ch/0Ah F PARTITION OR COLLECTION CONTAINS USER OBJECTS +2Ch/0Bh T NOT RESERVED +2Ch/0Ch D ORWRITE GENERATION DOES NOT MATCH +2Dh/00h T OVERWRITE ERROR ON UPDATE IN PLACE +2Eh/00h D WROM B INSUFFICIENT TIME FOR OPERATION +2Eh/01h D W OM B COMMAND TIMEOUT BEFORE PROCESSING +2Eh/02h D W OM B COMMAND TIMEOUT DURING PROCESSING +2Eh/03h D W OM B COMMAND TIMEOUT DURING PROCESSING DUE TO ERROR RECOVERY +2Fh/00h DTLPWROMAEBKVF COMMANDS CLEARED BY ANOTHER INITIATOR +2Fh/01h D COMMANDS CLEARED BY POWER LOSS NOTIFICATION +2Fh/02h DTLPWROMAEBKVF COMMANDS CLEARED BY DEVICE SERVER +2Fh/03h DTLPWROMAEBKVF SOME COMMANDS CLEARED BY QUEUING LAYER EVENT +30h/00h DT WROM BK INCOMPATIBLE MEDIUM INSTALLED +30h/01h DT WRO BK CANNOT READ MEDIUM - UNKNOWN FORMAT +30h/02h DT WRO BK CANNOT READ MEDIUM - INCOMPATIBLE FORMAT +30h/03h DT R M K CLEANING CARTRIDGE INSTALLED +30h/04h DT WRO BK CANNOT WRITE MEDIUM - UNKNOWN FORMAT +30h/05h DT WRO BK CANNOT WRITE MEDIUM - INCOMPATIBLE FORMAT +30h/06h DT WRO B CANNOT FORMAT MEDIUM - INCOMPATIBLE MEDIUM +30h/07h DTL WROMAEBKVF CLEANING FAILURE +30h/08h R CANNOT WRITE - APPLICATION CODE MISMATCH +30h/09h R CURRENT SESSION NOT FIXATED FOR APPEND +30h/0Ah DT WRO AEBK CLEANING REQUEST REJECTED +30h/0Ch T WORM MEDIUM - OVERWRITE ATTEMPTED +30h/0Dh T WORM MEDIUM - INTEGRITY CHECK +30h/10h R MEDIUM NOT FORMATTED +30h/11h M INCOMPATIBLE VOLUME TYPE +30h/12h M INCOMPATIBLE VOLUME QUALIFIER +30h/13h M CLEANING VOLUME EXPIRED +31h/00h DT WRO BK MEDIUM FORMAT CORRUPTED +31h/01h D L RO B FORMAT COMMAND FAILED +31h/02h R ZONED FORMATTING FAILED DUE TO SPARE LINKING +31h/03h D B SANITIZE COMMAND FAILED +32h/00h D W O BK NO DEFECT SPARE LOCATION AVAILABLE +32h/01h D W O BK DEFECT LIST UPDATE FAILURE +33h/00h T TAPE LENGTH ERROR +34h/00h DTLPWROMAEBKVF ENCLOSURE FAILURE +35h/00h DTLPWROMAEBKVF ENCLOSURE SERVICES FAILURE +35h/01h DTLPWROMAEBKVF UNSUPPORTED ENCLOSURE FUNCTION +35h/02h DTLPWROMAEBKVF ENCLOSURE SERVICES UNAVAILABLE +35h/03h DTLPWROMAEBKVF ENCLOSURE SERVICES TRANSFER FAILURE +35h/04h DTLPWROMAEBKVF ENCLOSURE SERVICES TRANSFER REFUSED +35h/05h DTL WROMAEBKVF ENCLOSURE SERVICES CHECKSUM ERROR +36h/00h L RIBBON, INK, OR TONER FAILURE +37h/00h DTL WROMAEBKVF ROUNDED PARAMETER +38h/00h B EVENT STATUS NOTIFICATION +38h/02h B ESN - POWER MANAGEMENT CLASS EVENT +38h/04h B ESN - MEDIA CLASS EVENT +38h/06h B ESN - DEVICE BUSY CLASS EVENT +38h/07h D THIN PROVISIONING SOFT THRESHOLD REACHED +39h/00h DTL WROMAE K SAVING PARAMETERS NOT SUPPORTED +3Ah/00h DTL WROM BK MEDIUM NOT PRESENT +3Ah/01h DT WROM BK MEDIUM NOT PRESENT - TRAY CLOSED +3Ah/02h DT WROM BK MEDIUM NOT PRESENT - TRAY OPEN +3Ah/03h DT WROM B MEDIUM NOT PRESENT - LOADABLE +3Ah/04h DT WRO B MEDIUM NOT PRESENT - MEDIUM AUXILIARY MEMORY ACCESSIBLE +3Bh/00h TL SEQUENTIAL POSITIONING ERROR +3Bh/01h T TAPE POSITION ERROR AT BEGINNING-OF-MEDIUM +3Bh/02h T TAPE POSITION ERROR AT END-OF-MEDIUM +3Bh/03h L TAPE OR ELECTRONIC VERTICAL FORMS UNIT NOT READY +3Bh/04h L SLEW FAILURE +3Bh/05h L PAPER JAM +3Bh/06h L FAILED TO SENSE TOP-OF-FORM +3Bh/07h L FAILED TO SENSE BOTTOM-OF-FORM +3Bh/08h T REPOSITION ERROR +3Bh/09h READ PAST END OF MEDIUM +3Bh/0Ah READ PAST BEGINNING OF MEDIUM +3Bh/0Bh POSITION PAST END OF MEDIUM +3Bh/0Ch T POSITION PAST BEGINNING OF MEDIUM +3Bh/0Dh DT WROM BK MEDIUM DESTINATION ELEMENT FULL +3Bh/0Eh DT WROM BK MEDIUM SOURCE ELEMENT EMPTY +3Bh/0Fh R END OF MEDIUM REACHED +3Bh/11h DT WROM BK MEDIUM MAGAZINE NOT ACCESSIBLE +3Bh/12h DT WROM BK MEDIUM MAGAZINE REMOVED +3Bh/13h DT WROM BK MEDIUM MAGAZINE INSERTED +3Bh/14h DT WROM BK MEDIUM MAGAZINE LOCKED +3Bh/15h DT WROM BK MEDIUM MAGAZINE UNLOCKED +3Bh/16h R MECHANICAL POSITIONING OR CHANGER ERROR +3Bh/17h F READ PAST END OF USER OBJECT +3Bh/18h M ELEMENT DISABLED +3Bh/19h M ELEMENT ENABLED +3Bh/1Ah M DATA TRANSFER DEVICE REMOVED +3Bh/1Bh M DATA TRANSFER DEVICE INSERTED +3Bh/1Ch T TOO MANY LOGICAL OBJECTS ON PARTITION TO SUPPORT OPERATION +3Ch/00h +3Dh/00h DTLPWROMAE K INVALID BITS IN IDENTIFY MESSAGE +3Eh/00h DTLPWROMAEBKVF LOGICAL UNIT HAS NOT SELF-CONFIGURED YET +3Eh/01h DTLPWROMAEBKVF LOGICAL UNIT FAILURE +3Eh/02h DTLPWROMAEBKVF TIMEOUT ON LOGICAL UNIT +3Eh/03h DTLPWROMAEBKVF LOGICAL UNIT FAILED SELF-TEST +3Eh/04h DTLPWROMAEBKVF LOGICAL UNIT UNABLE TO UPDATE SELF-TEST LOG +3Fh/00h DTLPWROMAEBKVF TARGET OPERATING CONDITIONS HAVE CHANGED +3Fh/01h DTLPWROMAEBKVF MICROCODE HAS BEEN CHANGED +3Fh/02h DTLPWROM BK CHANGED OPERATING DEFINITION +3Fh/03h DTLPWROMAEBKVF INQUIRY DATA HAS CHANGED +3Fh/04h DT WROMAEBK COMPONENT DEVICE ATTACHED +3Fh/05h DT WROMAEBK DEVICE IDENTIFIER CHANGED +3Fh/06h DT WROMAEB REDUNDANCY GROUP CREATED OR MODIFIED +3Fh/07h DT WROMAEB REDUNDANCY GROUP DELETED +3Fh/08h DT WROMAEB SPARE CREATED OR MODIFIED +3Fh/09h DT WROMAEB SPARE DELETED +3Fh/0Ah DT WROMAEBK VOLUME SET CREATED OR MODIFIED +3Fh/0Bh DT WROMAEBK VOLUME SET DELETED +3Fh/0Ch DT WROMAEBK VOLUME SET DEASSIGNED +3Fh/0Dh DT WROMAEBK VOLUME SET REASSIGNED +3Fh/0Eh DTLPWROMAE REPORTED LUNS DATA HAS CHANGED +3Fh/0Fh DTLPWROMAEBKVF ECHO BUFFER OVERWRITTEN +3Fh/10h DT WROM B MEDIUM LOADABLE +3Fh/11h DT WROM B MEDIUM AUXILIARY MEMORY ACCESSIBLE +3Fh/12h DTLPWR MAEBK F iSCSI IP ADDRESS ADDED +3Fh/13h DTLPWR MAEBK F iSCSI IP ADDRESS REMOVED +3Fh/14h DTLPWR MAEBK F iSCSI IP ADDRESS CHANGED +3Fh/15h DTLPWR MAEBK INSPECT REFERRALS SENSE DESCRIPTORS +40h/00h D RAM FAILURE (SHOULD USE 40 NN) +40h/NNh DTLPWROMAEBKVF DIAGNOSTIC FAILURE ON COMPONENT NN (80h-FFh) +41h/00h D DATA PATH FAILURE (SHOULD USE 40 NN) +42h/00h D POWER-ON OR SELF-TEST FAILURE (SHOULD USE 40 NN) +43h/00h DTLPWROMAEBKVF MESSAGE ERROR +44h/00h DTLPWROMAEBKVF INTERNAL TARGET FAILURE +44h/01h DT P MAEBKVF PERSISTENT RESERVATION INFORMATION LOST +44h/71h DT B ATA DEVICE FAILED SET FEATURES +45h/00h DTLPWROMAEBKVF SELECT OR RESELECT FAILURE +46h/00h DTLPWROM BK UNSUCCESSFUL SOFT RESET +47h/00h DTLPWROMAEBKVF SCSI PARITY ERROR +47h/01h DTLPWROMAEBKVF DATA PHASE CRC ERROR DETECTED +47h/02h DTLPWROMAEBKVF SCSI PARITY ERROR DETECTED DURING ST DATA PHASE +47h/03h DTLPWROMAEBKVF INFORMATION UNIT iuCRC ERROR DETECTED +47h/04h DTLPWROMAEBKVF ASYNCHRONOUS INFORMATION PROTECTION ERROR DETECTED +47h/05h DTLPWROMAEBKVF PROTOCOL SERVICE CRC ERROR +47h/06h DT MAEBKVF PHY TEST FUNCTION IN PROGRESS +47h/7Fh DT PWROMAEBK SOME COMMANDS CLEARED BY ISCSI PROTOCOL EVENT +48h/00h DTLPWROMAEBKVF INITIATOR DETECTED ERROR MESSAGE RECEIVED +49h/00h DTLPWROMAEBKVF INVALID MESSAGE ERROR +4Ah/00h DTLPWROMAEBKVF COMMAND PHASE ERROR +4Bh/00h DTLPWROMAEBKVF DATA PHASE ERROR +4Bh/01h DT PWROMAEBK INVALID TARGET PORT TRANSFER TAG RECEIVED +4Bh/02h DT PWROMAEBK TOO MUCH WRITE DATA +4Bh/03h DT PWROMAEBK ACK/NAK TIMEOUT +4Bh/04h DT PWROMAEBK NAK RECEIVED +4Bh/05h DT PWROMAEBK DATA OFFSET ERROR +4Bh/06h DT PWROMAEBK INITIATOR RESPONSE TIMEOUT +4Bh/07h DT PWROMAEBK F CONNECTION LOST +4Bh/08h DT PWROMAEBK F DATA-IN BUFFER OVERFLOW - DATA BUFFER SIZE +4Bh/09h DT PWROMAEBK F DATA-IN BUFFER OVERFLOW - DATA BUFFER DESCRIPTOR AREA +4Bh/0Ah DT PWROMAEBK F DATA-IN BUFFER ERROR +4Bh/0Bh DT PWROMAEBK F DATA-OUT BUFFER OVERFLOW - DATA BUFFER SIZE +4Bh/0Ch DT PWROMAEBK F DATA-OUT BUFFER OVERFLOW - DATA BUFFER DESCRIPTOR AREA +4Bh/0Dh DT PWROMAEBK F DATA-OUT BUFFER ERROR +4Bh/0Eh DT PWROMAEBK F PCIE FABRIC ERROR +4Bh/0Fh DT PWROMAEBK F PCIE COMPLETION TIMEOUT +4Bh/10h DT PWROMAEBK F PCIE COMPLETER ABORT +4Bh/11h DT PWROMAEBK F PCIE POISONED TLP RECEIVED +4Bh/12h DT PWROMAEBK F PCIE ECRC CHECK FAILED +4Bh/13h DT PWROMAEBK F PCIE UNSUPPORTED REQUEST +4Bh/14h DT PWROMAEBK F PCIE ACS VIOLATION +4Bh/15h DT PWROMAEBK F PCIE TLP PREFIX BLOCKED +4Ch/00h DTLPWROMAEBKVF LOGICAL UNIT FAILED SELF-CONFIGURATION +4Dh/NNh DTLPWROMAEBKVF TAGGED OVERLAPPED COMMANDS (NN = TASK TAG) +4Eh/00h DTLPWROMAEBKVF OVERLAPPED COMMANDS ATTEMPTED +4Fh/00h +50h/00h T WRITE APPEND ERROR +50h/01h T WRITE APPEND POSITION ERROR +50h/02h T POSITION ERROR RELATED TO TIMING +51h/00h T RO ERASE FAILURE +51h/01h R ERASE FAILURE - INCOMPLETE ERASE OPERATION DETECTED +52h/00h T CARTRIDGE FAULT +53h/00h DTL WROM BK MEDIA LOAD OR EJECT FAILED +53h/01h T UNLOAD TAPE FAILURE +53h/02h DT WROM BK MEDIUM REMOVAL PREVENTED +53h/03h M MEDIUM REMOVAL PREVENTED BY DATA TRANSFER ELEMENT +53h/04h T MEDIUM THREAD OR UNTHREAD FAILURE +53h/05h M VOLUME IDENTIFIER INVALID +53h/06h M VOLUME IDENTIFIER MISSING +53h/07h M DUPLICATE VOLUME IDENTIFIER +53h/08h M ELEMENT STATUS UNKNOWN +54h/00h P SCSI TO HOST SYSTEM INTERFACE FAILURE +55h/00h P SYSTEM RESOURCE FAILURE +55h/01h D O BK SYSTEM BUFFER FULL +55h/02h DTLPWROMAE K INSUFFICIENT RESERVATION RESOURCES +55h/03h DTLPWROMAE K INSUFFICIENT RESOURCES +55h/04h DTLPWROMAE K INSUFFICIENT REGISTRATION RESOURCES +55h/05h DT PWROMAEBK INSUFFICIENT ACCESS CONTROL RESOURCES +55h/06h DT WROM B AUXILIARY MEMORY OUT OF SPACE +55h/07h F QUOTA ERROR +55h/08h T MAXIMUM NUMBER OF SUPPLEMENTAL DECRYPTION KEYS EXCEEDED +55h/09h M MEDIUM AUXILIARY MEMORY NOT ACCESSIBLE +55h/0Ah M DATA CURRENTLY UNAVAILABLE +55h/0Bh DTLPWROMAEBKVF INSUFFICIENT POWER FOR OPERATION +55h/0Ch DT P B INSUFFICIENT RESOURCES TO CREATE ROD +55h/0Dh DT P B INSUFFICIENT RESOURCES TO CREATE ROD TOKEN +56h/00h +57h/00h R UNABLE TO RECOVER TABLE-OF-CONTENTS +58h/00h O GENERATION DOES NOT EXIST +59h/00h O UPDATED BLOCK READ +5Ah/00h DTLPWRO BK OPERATOR REQUEST OR STATE CHANGE INPUT +5Ah/01h DT WROM BK OPERATOR MEDIUM REMOVAL REQUEST +5Ah/02h DT WRO A BK OPERATOR SELECTED WRITE PROTECT +5Ah/03h DT WRO A BK OPERATOR SELECTED WRITE PERMIT +5Bh/00h DTLPWROM K LOG EXCEPTION +5Bh/01h DTLPWROM K THRESHOLD CONDITION MET +5Bh/02h DTLPWROM K LOG COUNTER AT MAXIMUM +5Bh/03h DTLPWROM K LOG LIST CODES EXHAUSTED +5Ch/00h D O RPL STATUS CHANGE +5Ch/01h D O SPINDLES SYNCHRONIZED +5Ch/02h D O SPINDLES NOT SYNCHRONIZED +5Dh/00h DTLPWROMAEBKVF FAILURE PREDICTION THRESHOLD EXCEEDED +5Dh/01h R B MEDIA FAILURE PREDICTION THRESHOLD EXCEEDED +5Dh/02h R LOGICAL UNIT FAILURE PREDICTION THRESHOLD EXCEEDED +5Dh/03h R SPARE AREA EXHAUSTION PREDICTION THRESHOLD EXCEEDED +5Dh/10h D B HARDWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE +5Dh/11h D B HARDWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH +5Dh/12h D B HARDWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH +5Dh/13h D B HARDWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH +5Dh/14h D B HARDWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS +5Dh/15h D B HARDWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH +5Dh/16h D B HARDWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH +5Dh/17h D B HARDWARE IMPENDING FAILURE CHANNEL PARAMETRICS +5Dh/18h D B HARDWARE IMPENDING FAILURE CONTROLLER DETECTED +5Dh/19h D B HARDWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE +5Dh/1Ah D B HARDWARE IMPENDING FAILURE SEEK TIME PERFORMANCE +5Dh/1Bh D B HARDWARE IMPENDING FAILURE SPIN-UP RETRY COUNT +5Dh/1Ch D B HARDWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT +5Dh/20h D B CONTROLLER IMPENDING FAILURE GENERAL HARD DRIVE FAILURE +5Dh/21h D B CONTROLLER IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH +5Dh/22h D B CONTROLLER IMPENDING FAILURE DATA ERROR RATE TOO HIGH +5Dh/23h D B CONTROLLER IMPENDING FAILURE SEEK ERROR RATE TOO HIGH +5Dh/24h D B CONTROLLER IMPENDING FAILURE TOO MANY BLOCK REASSIGNS +5Dh/25h D B CONTROLLER IMPENDING FAILURE ACCESS TIMES TOO HIGH +5Dh/26h D B CONTROLLER IMPENDING FAILURE START UNIT TIMES TOO HIGH +5Dh/27h D B CONTROLLER IMPENDING FAILURE CHANNEL PARAMETRICS +5Dh/28h D B CONTROLLER IMPENDING FAILURE CONTROLLER DETECTED +5Dh/29h D B CONTROLLER IMPENDING FAILURE THROUGHPUT PERFORMANCE +5Dh/2Ah D B CONTROLLER IMPENDING FAILURE SEEK TIME PERFORMANCE +5Dh/2Bh D B CONTROLLER IMPENDING FAILURE SPIN-UP RETRY COUNT +5Dh/2Ch D B CONTROLLER IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT +5Dh/30h D B DATA CHANNEL IMPENDING FAILURE GENERAL HARD DRIVE FAILURE +5Dh/31h D B DATA CHANNEL IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH +5Dh/32h D B DATA CHANNEL IMPENDING FAILURE DATA ERROR RATE TOO HIGH +5Dh/33h D B DATA CHANNEL IMPENDING FAILURE SEEK ERROR RATE TOO HIGH +5Dh/34h D B DATA CHANNEL IMPENDING FAILURE TOO MANY BLOCK REASSIGNS +5Dh/35h D B DATA CHANNEL IMPENDING FAILURE ACCESS TIMES TOO HIGH +5Dh/36h D B DATA CHANNEL IMPENDING FAILURE START UNIT TIMES TOO HIGH +5Dh/37h D B DATA CHANNEL IMPENDING FAILURE CHANNEL PARAMETRICS +5Dh/38h D B DATA CHANNEL IMPENDING FAILURE CONTROLLER DETECTED +5Dh/39h D B DATA CHANNEL IMPENDING FAILURE THROUGHPUT PERFORMANCE +5Dh/3Ah D B DATA CHANNEL IMPENDING FAILURE SEEK TIME PERFORMANCE +5Dh/3Bh D B DATA CHANNEL IMPENDING FAILURE SPIN-UP RETRY COUNT +5Dh/3Ch D B DATA CHANNEL IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT +5Dh/40h D B SERVO IMPENDING FAILURE GENERAL HARD DRIVE FAILURE +5Dh/41h D B SERVO IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH +5Dh/42h D B SERVO IMPENDING FAILURE DATA ERROR RATE TOO HIGH +5Dh/43h D B SERVO IMPENDING FAILURE SEEK ERROR RATE TOO HIGH +5Dh/44h D B SERVO IMPENDING FAILURE TOO MANY BLOCK REASSIGNS +5Dh/45h D B SERVO IMPENDING FAILURE ACCESS TIMES TOO HIGH +5Dh/46h D B SERVO IMPENDING FAILURE START UNIT TIMES TOO HIGH +5Dh/47h D B SERVO IMPENDING FAILURE CHANNEL PARAMETRICS +5Dh/48h D B SERVO IMPENDING FAILURE CONTROLLER DETECTED +5Dh/49h D B SERVO IMPENDING FAILURE THROUGHPUT PERFORMANCE +5Dh/4Ah D B SERVO IMPENDING FAILURE SEEK TIME PERFORMANCE +5Dh/4Bh D B SERVO IMPENDING FAILURE SPIN-UP RETRY COUNT +5Dh/4Ch D B SERVO IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT +5Dh/50h D B SPINDLE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE +5Dh/51h D B SPINDLE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH +5Dh/52h D B SPINDLE IMPENDING FAILURE DATA ERROR RATE TOO HIGH +5Dh/53h D B SPINDLE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH +5Dh/54h D B SPINDLE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS +5Dh/55h D B SPINDLE IMPENDING FAILURE ACCESS TIMES TOO HIGH +5Dh/56h D B SPINDLE IMPENDING FAILURE START UNIT TIMES TOO HIGH +5Dh/57h D B SPINDLE IMPENDING FAILURE CHANNEL PARAMETRICS +5Dh/58h D B SPINDLE IMPENDING FAILURE CONTROLLER DETECTED +5Dh/59h D B SPINDLE IMPENDING FAILURE THROUGHPUT PERFORMANCE +5Dh/5Ah D B SPINDLE IMPENDING FAILURE SEEK TIME PERFORMANCE +5Dh/5Bh D B SPINDLE IMPENDING FAILURE SPIN-UP RETRY COUNT +5Dh/5Ch D B SPINDLE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT +5Dh/60h D B FIRMWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE +5Dh/61h D B FIRMWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH +5Dh/62h D B FIRMWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH +5Dh/63h D B FIRMWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH +5Dh/64h D B FIRMWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS +5Dh/65h D B FIRMWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH +5Dh/66h D B FIRMWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH +5Dh/67h D B FIRMWARE IMPENDING FAILURE CHANNEL PARAMETRICS +5Dh/68h D B FIRMWARE IMPENDING FAILURE CONTROLLER DETECTED +5Dh/69h D B FIRMWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE +5Dh/6Ah D B FIRMWARE IMPENDING FAILURE SEEK TIME PERFORMANCE +5Dh/6Bh D B FIRMWARE IMPENDING FAILURE SPIN-UP RETRY COUNT +5Dh/6Ch D B FIRMWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT +5Dh/FFh DTLPWROMAEBKVF FAILURE PREDICTION THRESHOLD EXCEEDED (FALSE) +5Eh/00h DTLPWRO A K LOW POWER CONDITION ON +5Eh/01h DTLPWRO A K IDLE CONDITION ACTIVATED BY TIMER +5Eh/02h DTLPWRO A K STANDBY CONDITION ACTIVATED BY TIMER +5Eh/03h DTLPWRO A K IDLE CONDITION ACTIVATED BY COMMAND +5Eh/04h DTLPWRO A K STANDBY CONDITION ACTIVATED BY COMMAND +5Eh/05h DTLPWRO A K IDLE_B CONDITION ACTIVATED BY TIMER +5Eh/06h DTLPWRO A K IDLE_B CONDITION ACTIVATED BY COMMAND +5Eh/07h DTLPWRO A K IDLE_C CONDITION ACTIVATED BY TIMER +5Eh/08h DTLPWRO A K IDLE_C CONDITION ACTIVATED BY COMMAND +5Eh/09h DTLPWRO A K STANDBY_Y CONDITION ACTIVATED BY TIMER +5Eh/0Ah DTLPWRO A K STANDBY_Y CONDITION ACTIVATED BY COMMAND +5Eh/41h B POWER STATE CHANGE TO ACTIVE +5Eh/42h B POWER STATE CHANGE TO IDLE +5Eh/43h B POWER STATE CHANGE TO STANDBY +5Eh/45h B POWER STATE CHANGE TO SLEEP +5Eh/47h BK POWER STATE CHANGE TO DEVICE CONTROL +5Fh/00h +60h/00h LAMP FAILURE +61h/00h VIDEO ACQUISITION ERROR +61h/01h UNABLE TO ACQUIRE VIDEO +61h/02h OUT OF FOCUS +62h/00h SCAN HEAD POSITIONING ERROR +63h/00h R END OF USER AREA ENCOUNTERED ON THIS TRACK +63h/01h R PACKET DOES NOT FIT IN AVAILABLE SPACE +64h/00h R ILLEGAL MODE FOR THIS TRACK +64h/01h R INVALID PACKET SIZE +65h/00h DTLPWROMAEBKVF VOLTAGE FAULT +66h/00h AUTOMATIC DOCUMENT FEEDER COVER UP +66h/01h AUTOMATIC DOCUMENT FEEDER LIFT UP +66h/02h DOCUMENT JAM IN AUTOMATIC DOCUMENT FEEDER +66h/03h DOCUMENT MISS FEED AUTOMATIC IN DOCUMENT FEEDER +67h/00h A CONFIGURATION FAILURE +67h/01h A CONFIGURATION OF INCAPABLE LOGICAL UNITS FAILED +67h/02h A ADD LOGICAL UNIT FAILED +67h/03h A MODIFICATION OF LOGICAL UNIT FAILED +67h/04h A EXCHANGE OF LOGICAL UNIT FAILED +67h/05h A REMOVE OF LOGICAL UNIT FAILED +67h/06h A ATTACHMENT OF LOGICAL UNIT FAILED +67h/07h A CREATION OF LOGICAL UNIT FAILED +67h/08h A ASSIGN FAILURE OCCURRED +67h/09h A MULTIPLY ASSIGNED LOGICAL UNIT +67h/0Ah DTLPWROMAEBKVF SET TARGET PORT GROUPS COMMAND FAILED +67h/0Bh DT B ATA DEVICE FEATURE NOT ENABLED +68h/00h A LOGICAL UNIT NOT CONFIGURED +68h/01h D SUBSIDIARY LOGICAL UNIT NOT CONFIGURED +69h/00h A DATA LOSS ON LOGICAL UNIT +69h/01h A MULTIPLE LOGICAL UNIT FAILURES +69h/02h A PARITY/DATA MISMATCH +6Ah/00h A INFORMATIONAL, REFER TO LOG +6Bh/00h A STATE CHANGE HAS OCCURRED +6Bh/01h A REDUNDANCY LEVEL GOT BETTER +6Bh/02h A REDUNDANCY LEVEL GOT WORSE +6Ch/00h A REBUILD FAILURE OCCURRED +6Dh/00h A RECALCULATE FAILURE OCCURRED +6Eh/00h A COMMAND TO LOGICAL UNIT FAILED +6Fh/00h R COPY PROTECTION KEY EXCHANGE FAILURE - AUTHENTICATION FAILURE +6Fh/01h R COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT PRESENT +6Fh/02h R COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT ESTABLISHED +6Fh/03h R READ OF SCRAMBLED SECTOR WITHOUT AUTHENTICATION +6Fh/04h R MEDIA REGION CODE IS MISMATCHED TO LOGICAL UNIT REGION +6Fh/05h R DRIVE REGION MUST BE PERMANENT/REGION RESET COUNT ERROR +6Fh/06h R INSUFFICIENT BLOCK COUNT FOR BINDING NONCE RECORDING +6Fh/07h R CONFLICT IN BINDING NONCE RECORDING +70h/NNh T DECOMPRESSION EXCEPTION SHORT ALGORITHM ID OF NN +71h/00h T DECOMPRESSION EXCEPTION LONG ALGORITHM ID +72h/00h R SESSION FIXATION ERROR +72h/01h R SESSION FIXATION ERROR WRITING LEAD-IN +72h/02h R SESSION FIXATION ERROR WRITING LEAD-OUT +72h/03h R SESSION FIXATION ERROR - INCOMPLETE TRACK IN SESSION +72h/04h R EMPTY OR PARTIALLY WRITTEN RESERVED TRACK +72h/05h R NO MORE TRACK RESERVATIONS ALLOWED +72h/06h R RMZ EXTENSION IS NOT ALLOWED +72h/07h R NO MORE TEST ZONE EXTENSIONS ARE ALLOWED +73h/00h R CD CONTROL ERROR +73h/01h R POWER CALIBRATION AREA ALMOST FULL +73h/02h R POWER CALIBRATION AREA IS FULL +73h/03h R POWER CALIBRATION AREA ERROR +73h/04h R PROGRAM MEMORY AREA UPDATE FAILURE +73h/05h R PROGRAM MEMORY AREA IS FULL +73h/06h R RMA/PMA IS ALMOST FULL +73h/10h R CURRENT POWER CALIBRATION AREA ALMOST FULL +73h/11h R CURRENT POWER CALIBRATION AREA IS FULL +73h/17h R RDZ IS FULL +74h/00h T SECURITY ERROR +74h/01h T UNABLE TO DECRYPT DATA +74h/02h T UNENCRYPTED DATA ENCOUNTERED WHILE DECRYPTING +74h/03h T INCORRECT DATA ENCRYPTION KEY +74h/04h T CRYPTOGRAPHIC INTEGRITY VALIDATION FAILED +74h/05h T ERROR DECRYPTING DATA +74h/06h T UNKNOWN SIGNATURE VERIFICATION KEY +74h/07h T ENCRYPTION PARAMETERS NOT USEABLE +74h/08h DT R M E VF DIGITAL SIGNATURE VALIDATION FAILURE +74h/09h T ENCRYPTION MODE MISMATCH ON READ +74h/0Ah T ENCRYPTED BLOCK NOT RAW READ ENABLED +74h/0Bh T INCORRECT ENCRYPTION PARAMETERS +74h/0Ch DT R MAEBKV UNABLE TO DECRYPT PARAMETER LIST +74h/0Dh T ENCRYPTION ALGORITHM DISABLED +74h/10h DT R MAEBKV SA CREATION PARAMETER VALUE INVALID +74h/11h DT R MAEBKV SA CREATION PARAMETER VALUE REJECTED +74h/12h DT R MAEBKV INVALID SA USAGE +74h/21h T DATA ENCRYPTION CONFIGURATION PREVENTED +74h/30h DT R MAEBKV SA CREATION PARAMETER NOT SUPPORTED +74h/40h DT R MAEBKV AUTHENTICATION FAILED +74h/61h V EXTERNAL DATA ENCRYPTION KEY MANAGER ACCESS ERROR +74h/62h V EXTERNAL DATA ENCRYPTION KEY MANAGER ERROR +74h/63h V EXTERNAL DATA ENCRYPTION KEY NOT FOUND +74h/64h V EXTERNAL DATA ENCRYPTION REQUEST NOT AUTHORIZED +74h/6Eh T EXTERNAL DATA ENCRYPTION CONTROL TIMEOUT +74h/6Fh T EXTERNAL DATA ENCRYPTION CONTROL ERROR +74h/71h DT R M E V LOGICAL UNIT ACCESS NOT AUTHORIZED +74h/79h D SECURITY CONFLICT IN TRANSLATED DEVICE +75h/00h +76h/00h +77h/00h +78h/00h +79h/00h +7Ah/00h +7Bh/00h +7Ch/00h +7Dh/00h +7Eh/00h +7Fh/00h diff --git a/headers/private/drivers/scsi_sense.h b/headers/private/drivers/scsi_sense.h new file mode 100644 index 0000000000..f4f056c62d --- /dev/null +++ b/headers/private/drivers/scsi_sense.h @@ -0,0 +1,800 @@ +/* + * Copyright 2013, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Jérôme Duval + * + * Generated based on http://www.t10.org/lists/asc-num.txt 20130919 + * and http://www.t10.org/lists/2sensekey.htm + */ + + +// "standardized" error code to simplify handling of scsi errors +typedef enum { + err_act_ok, // executed successfully + err_act_retry, // failed, retry 3 times + err_act_fail, // failed, don't retry + err_act_many_retries, // failed, retry multiple times (currently 10 times) + err_act_start, // device requires a "start" command + err_act_invalid_req, // request is invalid + err_act_tur, // device requires a "test unit ready" command + err_act_rescan // device requires a rescan +} err_act; + + +typedef struct _scsi_sense_key_table +{ + uint8 key; + const char * label; + err_act action; + status_t err; +} scsi_sense_key_table; + + +scsi_sense_key_table sSCSISenseKeyTable[] = +{ + { 0x00, "No sense", err_act_ok, B_OK }, + { 0x01, "Recovered error", err_act_ok, B_OK }, + { 0x02, "Not ready", err_act_ok, B_DEV_NOT_READY }, + { 0x03, "Medium error", err_act_fail, B_DEV_RECALIBRATE_ERROR }, + { 0x04, "Hardware error", err_act_fail, B_DEV_SEEK_ERROR }, + { 0x05, "Illegal request", err_act_fail, B_DEV_INVALID_IOCTL }, + { 0x06, "Unit attention", err_act_fail, B_DEV_NOT_READY }, + { 0x07, "Data protect", err_act_fail, B_READ_ONLY_DEVICE }, + { 0x08, "Blank check", err_act_fail, B_DEV_UNREADABLE }, + { 0x09, "Vendor specific", err_act_fail, B_ERROR }, + { 0x0A, "Copy aborted", err_act_fail, B_ERROR }, + { 0x0B, "Aborted command", err_act_fail, B_CANCELED }, + { 0x0D, "Volume overflow", err_act_fail, B_DEV_SEEK_ERROR }, + { 0x0E, "Miscompare", err_act_ok, B_OK }, + { 0x0F, "Completed", err_act_ok, B_OK }, +}; + + +typedef struct _scsi_sense_asc_table +{ + unsigned short asc_ascq; + const char * label; + err_act action; + status_t err; +} scsi_sense_asc_table; + + +scsi_sense_asc_table sSCSISenseAscTable[] = +{ + { 0x0000, "No additional sense information", err_act_ok, B_OK }, // DTLPWROMAEBKVF + { 0x0001, "Filemark detected", err_act_fail, B_ERROR }, // T + { 0x0002, "End-of-partition/medium detected", err_act_fail, B_ERROR }, // T + { 0x0003, "Setmark detected", err_act_fail, B_ERROR }, // T + { 0x0004, "Beginning-of-partition/medium detected", err_act_fail, B_ERROR }, // T + { 0x0005, "End-of-data detected", err_act_fail, B_ERROR }, // TL + { 0x0006, "I/O process terminated", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x0007, "Programmable early warning detected", err_act_fail, B_ERROR }, // T + { 0x0011, "Audio play operation in progress", err_act_fail, B_DEV_NOT_READY }, // R + { 0x0012, "Audio play operation paused", err_act_ok, B_OK }, // R + { 0x0013, "Audio play operation successfully completed", err_act_ok, B_OK }, // R + { 0x0014, "Audio play operation stopped due to error", err_act_fail, B_ERROR }, // R + { 0x0015, "No current audio status to return", err_act_ok, B_OK }, // R + { 0x0016, "Operation in progress", err_act_fail, B_DEV_NOT_READY }, // DTLPWROMAEBKVF + { 0x0017, "Cleaning requested", err_act_fail, B_ERROR }, // DTL WROMAEBKVF + { 0x0018, "Erase operation in progress", err_act_fail, B_ERROR }, // T + { 0x0019, "Locate operation in progress", err_act_fail, B_ERROR }, // T + { 0x001A, "Rewind operation in progress", err_act_fail, B_ERROR }, // T + { 0x001B, "Set capacity operation in progress", err_act_fail, B_ERROR }, // T + { 0x001C, "Verify operation in progress", err_act_fail, B_ERROR }, // T + { 0x001D, "ATA pass through information available", err_act_fail, B_ERROR }, // DT B + { 0x001E, "Conflicting SA creation request", err_act_fail, B_ERROR }, // DT R MAEBKV + { 0x001F, "Logical unit transitioning to another power condition", err_act_fail, B_ERROR }, // DT B + { 0x0020, "Extended copy information available", err_act_fail, B_ERROR }, // DT P B + { 0x0100, "No index/sector signal", err_act_fail, B_ERROR }, // D W O BK + { 0x0200, "No seek complete", err_act_fail, B_ERROR }, // D WRO BK + { 0x0300, "Peripheral device write fault", err_act_fail, B_ERROR }, // DTL W O BK + { 0x0301, "No write current", err_act_fail, B_ERROR }, // T + { 0x0302, "Excessive write errors", err_act_fail, B_ERROR }, // T + { 0x0400, "Logical unit not ready, cause not reportable", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x0401, "Logical unit is in process of becoming ready", err_act_many_retries, B_DEV_NOT_READY }, // DTLPWROMAEBKVF + { 0x0402, "Logical unit not ready, initializing command required", err_act_start, B_NO_INIT }, // DTLPWROMAEBKVF + { 0x0403, "Logical unit not ready, manual intervention required", err_act_fail, B_DEV_NOT_READY }, // DTLPWROMAEBKVF + { 0x0404, "Logical unit not ready, format in progress", err_act_fail, B_DEV_NOT_READY }, // DTL RO B + { 0x0405, "Logical unit not ready, rebuild in progress", err_act_fail, B_DEV_NOT_READY }, // DT W O A BK F + { 0x0406, "Logical unit not ready, recalculation in progress", err_act_fail, B_DEV_NOT_READY }, // DT W O A BK + { 0x0407, "Logical unit not ready, operation in progress", err_act_fail, B_DEV_NOT_READY }, // DTLPWROMAEBKVF + { 0x0408, "Logical unit not ready, long write in progress", err_act_fail, B_DEV_NOT_READY }, // R + { 0x0409, "Logical unit not ready, self-test in progress", err_act_fail, B_DEV_NOT_READY }, // DTLPWROMAEBKVF + { 0x040A, "Logical unit not accessible, asymmetric access state transition", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x040B, "Logical unit not accessible, target port in standby state", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x040C, "Logical unit not accessible, target port in unavailable state", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x040D, "Logical unit not ready, structure check required", err_act_fail, B_ERROR }, // F + { 0x0410, "Logical unit not ready, auxiliary memory not accessible", err_act_fail, B_ERROR }, // DT WROM B + { 0x0411, "Logical unit not ready, notify (enable spinup) required", err_act_tur, B_DEV_NOT_READY }, // DT WRO AEB VF + { 0x0412, "Logical unit not ready, offline", err_act_fail, B_ERROR }, // M V + { 0x0413, "Logical unit not ready, SA creation in progress", err_act_fail, B_ERROR }, // DT R MAEBKV + { 0x0414, "Logical unit not ready, space allocation in progress", err_act_fail, B_ERROR }, // D B + { 0x0415, "Logical unit not ready, robotics disabled", err_act_fail, B_ERROR }, // M + { 0x0416, "Logical unit not ready, configuration required", err_act_fail, B_ERROR }, // M + { 0x0417, "Logical unit not ready, calibration required", err_act_fail, B_ERROR }, // M + { 0x0418, "Logical unit not ready, a door is open", err_act_fail, B_ERROR }, // M + { 0x0419, "Logical unit not ready, operating in sequential mode", err_act_fail, B_ERROR }, // M + { 0x041A, "Logical unit not ready, START STOP unit command in progress", err_act_fail, B_ERROR }, // D B + { 0x041B, "Logical unit not ready, sanitize in progress", err_act_fail, B_ERROR }, // D B + { 0x041C, "Logical unit not ready, additional power use not yet granted", err_act_fail, B_ERROR }, // DT MAEB + { 0x041D, "Logical unit not ready, configuration in progress", err_act_fail, B_ERROR }, // D + { 0x041E, "Logical unit not ready, microcode activation required", err_act_fail, B_ERROR }, // D + { 0x0500, "Logical unit does not respond to selection", err_act_fail, B_ERROR }, // DTL WROMAEBKVF + { 0x0600, "No reference position found", err_act_fail, B_ERROR }, // D WROM BK + { 0x0700, "Multiple peripheral devices selected", err_act_fail, B_ERROR }, // DTL WROM BK + { 0x0800, "Logical unit communication failure", err_act_fail, B_ERROR }, // DTL WROMAEBKVF + { 0x0801, "Logical unit communication time-out", err_act_fail, B_ERROR }, // DTL WROMAEBKVF + { 0x0802, "Logical unit communication parity error", err_act_fail, B_ERROR }, // DTL WROMAEBKVF + { 0x0803, "Logical unit communication CRC error (Ultra-DMA/32)", err_act_fail, B_ERROR }, // DT ROM BK + { 0x0804, "Unreachable copy target", err_act_fail, B_ERROR }, // DTLPWRO K + { 0x0900, "Track following error", err_act_fail, B_ERROR }, // DT WRO B + { 0x0901, "Tracking servo failure", err_act_fail, B_ERROR }, // WRO K + { 0x0902, "Focus servo failure", err_act_fail, B_ERROR }, // WRO K + { 0x0903, "Spindle servo failure", err_act_fail, B_ERROR }, // WRO + { 0x0904, "Head select fault", err_act_fail, B_ERROR }, // DT WRO B + { 0x0A00, "Error log overflow", err_act_fail, ENOSPC }, // DTLPWROMAEBKVF + { 0x0B00, "Warning", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x0B01, "Warning - specified temperature exceeded", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x0B02, "Warning - enclosure degraded", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x0B03, "Warning - background self-test failed", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x0B04, "Warning - background pre-scan detected medium error", err_act_fail, B_ERROR }, // DTLPWRO AEBKVF + { 0x0B05, "Warning - background medium scan detected medium error", err_act_fail, B_ERROR }, // DTLPWRO AEBKVF + { 0x0B06, "Warning - non-volatile cache now volatile", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x0B07, "Warning - degraded power to non-volatile cache", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x0B08, "Warning - power loss expected", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x0B09, "Warning - device statistics notification active", err_act_fail, B_ERROR }, // D + { 0x0C00, "Write error", err_act_fail, B_ERROR }, // T R + { 0x0C01, "Write error - recovered with auto reallocation", err_act_ok, B_OK }, // K + { 0x0C02, "Write error - auto reallocation failed", err_act_fail, B_ERROR }, // D W O BK + { 0x0C03, "Write error - recommend reassignment", err_act_fail, B_ERROR }, // D W O BK + { 0x0C04, "Compression check miscompare error", err_act_fail, B_ERROR }, // DT W O B + { 0x0C05, "Data expansion occurred during compression", err_act_fail, B_ERROR }, // DT W O B + { 0x0C06, "Block not compressible", err_act_fail, B_ERROR }, // DT W O B + { 0x0C07, "Write error - recovery needed", err_act_fail, B_ERROR }, // R + { 0x0C08, "Write error - recovery failed", err_act_fail, B_ERROR }, // R + { 0x0C09, "Write error - loss of streaming", err_act_fail, B_ERROR }, // R + { 0x0C0A, "Write error - padding blocks added", err_act_fail, B_ERROR }, // R + { 0x0C0B, "Auxiliary memory write error", err_act_fail, B_ERROR }, // DT WROM B + { 0x0C0C, "Write error - unexpected unsolicited data", err_act_fail, B_ERROR }, // DTLPWRO AEBKVF + { 0x0C0D, "Write error - not enough unsolicited data", err_act_fail, B_ERROR }, // DTLPWRO AEBKVF + { 0x0C0E, "Multiple write errors", err_act_fail, B_ERROR }, // DT W O BK + { 0x0C0F, "Defects in error window", err_act_fail, B_ERROR }, // R + { 0x0D00, "Error detected by third party temporary initiator", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x0D01, "Third party device failure", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x0D02, "Copy target device not reachable", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x0D03, "Incorrect copy target device type", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x0D04, "Copy target device data underrun", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x0D05, "Copy target device data overrun", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x0E00, "Invalid information unit", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x0E01, "Information unit too short", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x0E02, "Information unit too long", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x0E03, "Invalid field in command information unit", err_act_fail, B_ERROR }, // DT P R MAEBK F + { 0x1000, "ID CRC or ECC error", err_act_fail, B_ERROR }, // D W O BK + { 0x1001, "Logical block guard check failed", err_act_fail, B_ERROR }, // DT W O + { 0x1002, "Logical block application tag check failed", err_act_fail, B_ERROR }, // DT W O + { 0x1003, "Logical block reference tag check failed", err_act_fail, B_ERROR }, // DT W O + { 0x1004, "Logical block protection error on recover buffered data", err_act_fail, B_ERROR }, // T + { 0x1005, "Logical block protection method error", err_act_fail, B_ERROR }, // T + { 0x1100, "Unrecovered read error", err_act_fail, B_IO_ERROR }, // DT WRO BK + { 0x1101, "Read retries exhausted", err_act_fail, B_IO_ERROR }, // DT WRO BK + { 0x1102, "Error too long to correct", err_act_fail, B_IO_ERROR }, // DT WRO BK + { 0x1103, "Multiple read errors", err_act_fail, B_IO_ERROR }, // DT W O BK + { 0x1104, "Unrecovered read error - auto reallocate failed", err_act_fail, B_IO_ERROR }, // D W O BK + { 0x1105, "L-EC uncorrectable error", err_act_fail, B_IO_ERROR }, // WRO B + { 0x1106, "CIRC unrecovered error", err_act_fail, B_IO_ERROR }, // WRO B + { 0x1107, "Data re-synchronization error", err_act_fail, B_ERROR }, // W O B + { 0x1108, "Incomplete block read", err_act_fail, B_ERROR }, // T + { 0x1109, "No gap found", err_act_fail, B_ERROR }, // T + { 0x110A, "Miscorrected error", err_act_fail, B_ERROR }, // DT O BK + { 0x110B, "Unrecovered read error - recommend reassignment", err_act_fail, B_IO_ERROR }, // D W O BK + { 0x110C, "Unrecovered read error - recommend rewrite the data", err_act_fail, B_IO_ERROR }, // D W O BK + { 0x110D, "De-compression CRC error", err_act_fail, B_ERROR }, // DT WRO B + { 0x110E, "Cannot decompress using declared algorithm", err_act_fail, B_ERROR }, // DT WRO B + { 0x110F, "Error readingUPC/EAN number", err_act_fail, B_ERROR }, // R + { 0x1110, "Error reading ISRC number", err_act_fail, B_ERROR }, // R + { 0x1111, "Read error - loss of streaming", err_act_fail, B_ERROR }, // R + { 0x1112, "Auxiliary memory read error", err_act_fail, B_ERROR }, // DT WROM B + { 0x1113, "Read error - failed retransmission request", err_act_fail, B_ERROR }, // DTLPWRO AEBKVF + { 0x1114, "Read error - LBA marked bad by application client", err_act_fail, B_ERROR }, // D + { 0x1115, "Write after sanitize required", err_act_fail, B_ERROR }, // D + { 0x1200, "Address mark not found for ID field", err_act_fail, B_ERROR }, // D W O BK + { 0x1300, "Address mark not found for data field", err_act_fail, B_ERROR }, // D W O BK + { 0x1400, "Recorded entity not found", err_act_fail, B_ERROR }, // DTL WRO BK + { 0x1401, "Record not found", err_act_fail, B_ERROR }, // DT WRO BK + { 0x1402, "Filemark or setmark not found", err_act_fail, B_ERROR }, // T + { 0x1403, "End-of-data not found", err_act_fail, B_ERROR }, // T + { 0x1404, "Block sequence error", err_act_fail, B_ERROR }, // T + { 0x1405, "Record not found - recommend reassignment", err_act_fail, B_ERROR }, // DT W O BK + { 0x1406, "Record not found - data auto-reallocated", err_act_fail, B_ERROR }, // DT W O BK + { 0x1407, "Locate operation failure", err_act_fail, B_ERROR }, // T + { 0x1500, "Random positioning error", err_act_fail, B_ERROR }, // DTL WROM BK + { 0x1501, "Mechanical positioning error", err_act_fail, B_ERROR }, // DTL WROM BK + { 0x1502, "Positioning error detected by read of medium", err_act_fail, B_ERROR }, // DT WRO BK + { 0x1600, "Data synchronization mark error", err_act_fail, B_ERROR }, // D W O BK + { 0x1601, "Data sync error - data rewritten", err_act_fail, B_ERROR }, // D W O BK + { 0x1602, "Data sync error - recommend rewrite", err_act_fail, B_ERROR }, // D W O BK + { 0x1603, "Data sync error - data auto-reallocated", err_act_ok, B_OK }, // D W O BK + { 0x1604, "Data sync error - recommend reassignment", err_act_fail, B_ERROR }, // D W O BK + { 0x1700, "Recovered data with no error correction applied", err_act_ok, B_OK }, // DT WRO BK + { 0x1701, "Recovered data with retries", err_act_ok, B_OK }, // DT WRO BK + { 0x1702, "Recovered data with positive head offset", err_act_ok, B_OK }, // DT WRO BK + { 0x1703, "Recovered data with negative head offset", err_act_ok, B_OK }, // DT WRO BK + { 0x1704, "Recovered data with retries and/or CIRC applied", err_act_ok, B_OK }, // WRO B + { 0x1705, "Recovered data using previous sector ID", err_act_ok, B_OK }, // D WRO BK + { 0x1706, "Recovered data without ECC - data auto-reallocated", err_act_ok, B_OK }, // D W O BK + { 0x1707, "Recovered data without ECC - recommend reassignment", err_act_ok, B_OK }, // D WRO BK + { 0x1708, "Recovered data without ECC - recommend rewrite", err_act_ok, B_OK }, // D WRO BK + { 0x1709, "Recovered data without ECC - data rewritten", err_act_ok, B_OK }, // D WRO BK + { 0x1800, "Recovered data with error correction applied", err_act_ok, B_OK }, // DT WRO BK + { 0x1801, "Recovered data with error corr. & retries applied", err_act_ok, B_OK }, // D WRO BK + { 0x1802, "Recovered data - data auto-reallocated", err_act_ok, B_OK }, // D WRO BK + { 0x1803, "Recovered data with CIRC", err_act_ok, B_OK }, // R + { 0x1804, "Recovered data with l-EC", err_act_ok, B_OK }, // R + { 0x1805, "Recovered data - recommend reassignment", err_act_ok, B_OK }, // D WRO BK + { 0x1806, "Recovered data - recommend rewrite", err_act_ok, B_OK }, // D WRO BK + { 0x1807, "Recovered data with ECC - data rewritten", err_act_ok, B_OK }, // D W O BK + { 0x1808, "Recovered data with linking", err_act_fail, B_ERROR }, // R + { 0x1900, "Defect list error", err_act_fail, B_ERROR }, // D O K + { 0x1901, "Defect list not available", err_act_fail, B_ERROR }, // D O K + { 0x1902, "Defect list error in primary list", err_act_fail, B_ERROR }, // D O K + { 0x1903, "Defect list error in grown list", err_act_fail, B_ERROR }, // D O K + { 0x1A00, "Parameter list length error", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x1B00, "Synchronous data transfer error", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x1C00, "Defect list not found", err_act_fail, B_ERROR }, // D O BK + { 0x1C01, "Primary defect list not found", err_act_fail, B_ERROR }, // D O BK + { 0x1C02, "Grown defect list not found", err_act_fail, B_ERROR }, // D O BK + { 0x1D00, "Miscompare during verify operation", err_act_fail, B_ERROR }, // DT WRO BK + { 0x1D01, "Miscompare verify of unmapped LBA", err_act_fail, B_ERROR }, // D B + { 0x1E00, "Recovered ID with ECC correction", err_act_ok, B_OK }, // D W O BK + { 0x1F00, "Partial defect list transfer", err_act_fail, B_ERROR }, // D O K + { 0x2000, "Invalid command operation code", err_act_fail, B_DEV_INVALID_IOCTL }, // DTLPWROMAEBKVF + { 0x2001, "Access denied - initiator pending-enrolled", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x2002, "Access denied - no access rights", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x2003, "Access denied - invalid mgmt ID key", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x2004, "Illegal command while in write capable state", err_act_fail, B_ERROR }, // T + { 0x2005, "Obsolete", err_act_fail, B_ERROR }, // T + { 0x2006, "Illegal command while in explicit address mode", err_act_fail, B_ERROR }, // T + { 0x2007, "Illegal command while in implicit address mode", err_act_fail, B_ERROR }, // T + { 0x2008, "Access denied - enrollment conflict", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x2009, "Access denied - invalid LU identifier", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x200A, "Access denied - invalid proxy token", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x200B, "Access denied - ACL LUN conflict", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x200C, "Illegal command when not in append-only mode", err_act_fail, B_DEV_INVALID_IOCTL }, // T + { 0x2100, "Logical block address out of range", err_act_fail, B_BAD_VALUE }, // DT WRO BK + { 0x2101, "Invalid element address", err_act_fail, B_BAD_VALUE }, // DT WROM BK + { 0x2102, "Invalid address for write", err_act_fail, B_ERROR }, // R + { 0x2103, "Invalid write crossing layer jump", err_act_fail, B_ERROR }, // R + { 0x2200, "Illegal function (use 20 00, 24 00, or 26 00)", err_act_fail, B_DEV_INVALID_IOCTL }, // D + { 0x2300, "Invalid token operation, cause not reportable", err_act_fail, B_ERROR }, // DT P B + { 0x2301, "Invalid token operation, unsupported token type", err_act_fail, B_ERROR }, // DT P B + { 0x2302, "Invalid token operation, remote token usage not supported", err_act_fail, B_ERROR }, // DT P B + { 0x2303, "Invalid token operation, remote ROD token creation not supported", err_act_fail, B_ERROR }, // DT P B + { 0x2304, "Invalid token operation, token unknown", err_act_fail, B_ERROR }, // DT P B + { 0x2305, "Invalid token operation, token corrupt", err_act_fail, B_ERROR }, // DT P B + { 0x2306, "Invalid token operation, token revoked", err_act_fail, B_ERROR }, // DT P B + { 0x2307, "Invalid token operation, token expired", err_act_fail, B_ERROR }, // DT P B + { 0x2308, "Invalid token operation, token cancelled", err_act_fail, B_ERROR }, // DT P B + { 0x2309, "Invalid token operation, token deleted", err_act_fail, B_ERROR }, // DT P B + { 0x230A, "Invalid token operation, invalid token length", err_act_fail, B_ERROR }, // DT P B + { 0x2400, "Invalid field in CDB", err_act_fail, B_BAD_VALUE }, // DTLPWROMAEBKVF + { 0x2401, "CDB decryption error", err_act_fail, B_ERROR }, // DTLPWRO AEBKVF + { 0x2402, "Obsolete", err_act_fail, B_ERROR }, // T + { 0x2403, "Obsolete", err_act_fail, B_ERROR }, // T + { 0x2404, "Security audit value frozen", err_act_fail, B_ERROR }, // F + { 0x2405, "Security working key frozen", err_act_fail, B_ERROR }, // F + { 0x2406, "NONCE not unique", err_act_fail, B_ERROR }, // F + { 0x2407, "NONCE timestamp out of range", err_act_fail, B_ERROR }, // F + { 0x2408, "Invalid XCDB", err_act_fail, B_ERROR }, // DT R MAEBKV + { 0x2500, "Logical unit not supported", err_act_fail, ENXIO }, // DTLPWROMAEBKVF + { 0x2600, "Invalid field in parameter list", err_act_fail, B_BAD_VALUE }, // DTLPWROMAEBKVF + { 0x2601, "Parameter not supported", err_act_fail, B_BAD_VALUE }, // DTLPWROMAEBKVF + { 0x2602, "Parameter value invalid", err_act_fail, B_BAD_VALUE }, // DTLPWROMAEBKVF + { 0x2603, "Threshold parameters not supported", err_act_fail, B_BAD_VALUE }, // DTLPWROMAE K + { 0x2604, "Invalid release of persistent reservation", err_act_fail, B_BAD_VALUE }, // DTLPWROMAEBKVF + { 0x2605, "Data decryption error", err_act_fail, B_ERROR }, // DTLPWRO A BK + { 0x2606, "Too many target descriptors", err_act_fail, B_ERROR }, // DTLPWRO K + { 0x2607, "Unsupported target descriptor type code", err_act_fail, B_ERROR }, // DTLPWRO K + { 0x2608, "Too many segment descriptors", err_act_fail, B_ERROR }, // DTLPWRO K + { 0x2609, "Unsupported segment descriptor type code", err_act_fail, B_ERROR }, // DTLPWRO K + { 0x260A, "Unexpected inexact segment", err_act_fail, B_ERROR }, // DTLPWRO K + { 0x260B, "Inline data length exceeded", err_act_fail, B_ERROR }, // DTLPWRO K + { 0x260C, "Invalid operation for copy source or destination", err_act_fail, B_ERROR }, // DTLPWRO K + { 0x260D, "Copy segment granularity violation", err_act_fail, B_ERROR }, // DTLPWRO K + { 0x260E, "Invalid parameter while port is enabled", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x260F, "Invalid data-out buffer integrity check value", err_act_fail, B_ERROR }, // F + { 0x2610, "Data decryption key fail limit reached", err_act_fail, B_ERROR }, // T + { 0x2611, "Incomplete key-associated data set", err_act_fail, B_ERROR }, // T + { 0x2612, "Vendor specific key reference not found", err_act_fail, B_ERROR }, // T + { 0x2700, "Write protected", err_act_fail, B_READ_ONLY_DEVICE }, // DT WRO BK + { 0x2701, "Hardware write protected", err_act_fail, B_READ_ONLY_DEVICE }, // DT WRO BK + { 0x2702, "Logical unit software write protected", err_act_fail, B_READ_ONLY_DEVICE }, // DT WRO BK + { 0x2703, "Associated write protect", err_act_fail, B_READ_ONLY_DEVICE }, // T R + { 0x2704, "Persistent write protect", err_act_fail, B_READ_ONLY_DEVICE }, // T R + { 0x2705, "Permanent write protect", err_act_fail, B_READ_ONLY_DEVICE }, // T R + { 0x2706, "Conditional write protect", err_act_fail, B_READ_ONLY_DEVICE }, // R F + { 0x2707, "Space allocation failed write protect", err_act_fail, B_READ_ONLY_DEVICE }, // D B + { 0x2800, "Not ready to ready change, medium may have changed", err_act_fail, B_DEV_MEDIA_CHANGED }, // DTLPWROMAEBKVF + { 0x2801, "Import or export element accessed", err_act_fail, ENXIO }, // DT WROM B + { 0x2802, "Format-layer may have changed", err_act_fail, B_DEV_MEDIA_CHANGED }, // R + { 0x2803, "Import/export element accessed, medium changed", err_act_fail, B_ERROR }, // M + { 0x2900, "Power on, reset, or bus device reset occurred", err_act_retry, B_DEV_NOT_READY }, // DTLPWROMAEBKVF + { 0x2901, "Power on occurred", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2902, "SCSI bus reset occurred", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2903, "Bus device reset function occurred", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2904, "Device internal reset", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2905, "Transceiver mode changed to single-ended", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2906, "Transceiver mode changed to LVD", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2907, "I_T nexus loss occurred", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2A00, "Parameters changed", err_act_fail, B_ERROR }, // DTL WROMAEBKVF + { 0x2A01, "Mode parameters changed", err_act_fail, B_ERROR }, // DTL WROMAEBKVF + { 0x2A02, "Log parameters changed", err_act_fail, B_ERROR }, // DTL WROMAE K + { 0x2A03, "Reservations preempted", err_act_fail, B_ERROR }, // DTLPWROMAE K + { 0x2A04, "Reservations released", err_act_fail, B_ERROR }, // DTLPWROMAE + { 0x2A05, "Registrations preempted", err_act_fail, B_ERROR }, // DTLPWROMAE + { 0x2A06, "Asymmetric access state changed", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2A07, "Implicit asymmetric access state transition failed", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2A08, "Priority changed", err_act_fail, B_ERROR }, // DT WROMAEBKVF + { 0x2A09, "Capacity data has changed", err_act_fail, B_ERROR }, // D + { 0x2A0A, "Error history I_T nexus cleared", err_act_fail, B_ERROR }, // DT + { 0x2A0B, "Error history snapshot released", err_act_fail, B_ERROR }, // DT + { 0x2A0C, "Error recovery attributes have changed", err_act_fail, B_ERROR }, // F + { 0x2A0D, "Data encryption capabilities changed", err_act_fail, B_ERROR }, // T + { 0x2A10, "Timestamp changed", err_act_fail, B_ERROR }, // DT M E V + { 0x2A11, "Data encryption parameters changed by another I_T nexus", err_act_fail, B_ERROR }, // T + { 0x2A12, "Data encryption parameters changed by vendor specific event", err_act_fail, B_ERROR }, // T + { 0x2A13, "Data encryption key instance counter has changed", err_act_fail, B_ERROR }, // T + { 0x2A14, "SA creation capabilities data has changed", err_act_fail, B_ERROR }, // DT R MAEBKV + { 0x2A15, "Medium removal prevention preempted", err_act_fail, B_ERROR }, // T M V + { 0x2B00, "Copy cannot execute since host cannot disconnect", err_act_fail, B_ERROR }, // DTLPWRO K + { 0x2C00, "Command sequence error", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2C01, "Too many windows specified", err_act_fail, B_ERROR }, // + { 0x2C02, "Invalid combination of windows specified", err_act_fail, B_ERROR }, // + { 0x2C03, "Current program area is not empty", err_act_fail, B_ERROR }, // R + { 0x2C04, "Current program area is empty", err_act_fail, B_ERROR }, // R + { 0x2C05, "Illegal power condition request", err_act_fail, B_ERROR }, // B + { 0x2C06, "Persistent prevent conflict", err_act_fail, B_ERROR }, // R + { 0x2C07, "Previous busy status", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2C08, "Previous task set full status", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2C09, "Previous reservation conflict status", err_act_fail, B_ERROR }, // DTLPWROM EBKVF + { 0x2C0A, "Partition or collection contains user objects", err_act_fail, B_ERROR }, // F + { 0x2C0B, "Not reserved", err_act_fail, B_ERROR }, // T + { 0x2C0C, "ORWRITE generation does not match", err_act_fail, B_ERROR }, // D + { 0x2D00, "Overwrite error on update in place", err_act_fail, B_ERROR }, // T + { 0x2E00, "Insufficient time for operation", err_act_fail, B_ERROR }, // D WROM B + { 0x2E01, "Command timeout before processing", err_act_fail, B_ERROR }, // D W OM B + { 0x2E02, "Command timeout during processing", err_act_fail, B_ERROR }, // D W OM B + { 0x2E03, "Command timeout during processing due to error recovery", err_act_fail, B_ERROR }, // D W OM B + { 0x2F00, "Commands cleared by another initiator", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2F01, "Commands cleared by power loss notification", err_act_fail, B_ERROR }, // D + { 0x2F02, "Commands cleared by device server", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x2F03, "Some commands cleared by queuing layer event", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3000, "Incompatible medium installed", err_act_fail, B_ERROR }, // DT WROM BK + { 0x3001, "Cannot read medium - unknown format", err_act_fail, B_ERROR }, // DT WRO BK + { 0x3002, "Cannot read medium - incompatible format", err_act_fail, B_ERROR }, // DT WRO BK + { 0x3003, "Cleaning cartridge installed", err_act_fail, B_ERROR }, // DT R M K + { 0x3004, "Cannot write medium - unknown format", err_act_fail, B_ERROR }, // DT WRO BK + { 0x3005, "Cannot write medium - incompatible format", err_act_fail, B_ERROR }, // DT WRO BK + { 0x3006, "Cannot format medium - incompatible medium", err_act_fail, B_ERROR }, // DT WRO B + { 0x3007, "Cleaning failure", err_act_fail, B_ERROR }, // DTL WROMAEBKVF + { 0x3008, "Cannot write - application code mismatch", err_act_fail, B_ERROR }, // R + { 0x3009, "Current session not fixated for append", err_act_fail, B_ERROR }, // R + { 0x300A, "Cleaning request rejected", err_act_fail, B_ERROR }, // DT WRO AEBK + { 0x300C, "WORM medium - overwrite attempted", err_act_fail, B_ERROR }, // T + { 0x300D, "WORM medium - integrity check", err_act_fail, B_ERROR }, // T + { 0x3010, "Medium not formatted", err_act_fail, B_ERROR }, // R + { 0x3011, "Incompatible volume type", err_act_fail, B_ERROR }, // M + { 0x3012, "Incompatible volume qualifier", err_act_fail, B_ERROR }, // M + { 0x3013, "Cleaning volume expired", err_act_fail, B_ERROR }, // M + { 0x3100, "Medium format corrupted", err_act_fail, B_ERROR }, // DT WRO BK + { 0x3101, "Format command failed", err_act_fail, B_ERROR }, // D L RO B + { 0x3102, "Zoned formatting failed due to spare linking", err_act_fail, B_ERROR }, // R + { 0x3103, "SANITIZE command failed", err_act_fail, B_ERROR }, // D B + { 0x3200, "No defect spare location available", err_act_fail, B_ERROR }, // D W O BK + { 0x3201, "Defect list update failure", err_act_fail, B_ERROR }, // D W O BK + { 0x3300, "Tape length error", err_act_fail, B_ERROR }, // T + { 0x3400, "Enclosure failure", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3500, "Enclosure services failure", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3501, "Unsupported enclosure function", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3502, "Enclosure services unavailable", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3503, "Enclosure services transfer failure", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3504, "Enclosure services transfer refused", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3505, "Enclosure services checksum error", err_act_fail, B_ERROR }, // DTL WROMAEBKVF + { 0x3600, "Ribbon, ink, or toner failure", err_act_fail, B_ERROR }, // L + { 0x3700, "Rounded parameter", err_act_fail, B_ERROR }, // DTL WROMAEBKVF + { 0x3800, "Event status notification", err_act_fail, B_ERROR }, // B + { 0x3802, "ESN - power management class event", err_act_fail, B_ERROR }, // B + { 0x3804, "ESN - media class event", err_act_fail, B_ERROR }, // B + { 0x3806, "ESN - device busy class event", err_act_fail, B_ERROR }, // B + { 0x3807, "Thin provisioning soft threshold reached", err_act_fail, B_ERROR }, // D + { 0x3900, "Saving parameters not supported", err_act_fail, B_ERROR }, // DTL WROMAE K + { 0x3A00, "Medium not present", err_act_fail, B_DEV_NO_MEDIA }, // DTL WROM BK + { 0x3A01, "Medium not present - tray closed", err_act_fail, B_DEV_NO_MEDIA }, // DT WROM BK + { 0x3A02, "Medium not present - tray open", err_act_fail, B_DEV_NO_MEDIA }, // DT WROM BK + { 0x3A03, "Medium not present - loadable", err_act_fail, B_DEV_NO_MEDIA }, // DT WROM B + { 0x3A04, "Medium not present - medium auxiliary memory accessible", err_act_fail, B_DEV_NO_MEDIA }, // DT WRO B + { 0x3B00, "Sequential positioning error", err_act_fail, B_ERROR }, // TL + { 0x3B01, "Tape position error at beginning-of-medium", err_act_fail, B_ERROR }, // T + { 0x3B02, "Tape position error at end-of-medium", err_act_fail, B_ERROR }, // T + { 0x3B03, "Tape or electronic vertical forms unit not ready", err_act_fail, B_ERROR }, // L + { 0x3B04, "Slew failure", err_act_fail, B_ERROR }, // L + { 0x3B05, "Paper jam", err_act_fail, B_ERROR }, // L + { 0x3B06, "Failed to sense top-of-form", err_act_fail, B_ERROR }, // L + { 0x3B07, "Failed to sense bottom-of-form", err_act_fail, B_ERROR }, // L + { 0x3B08, "Reposition error", err_act_fail, B_ERROR }, // T + { 0x3B09, "Read past end of medium", err_act_fail, B_ERROR }, // + { 0x3B0A, "Read past beginning of medium", err_act_fail, B_ERROR }, // + { 0x3B0B, "Position past end of medium", err_act_fail, B_ERROR }, // + { 0x3B0C, "Position past beginning of medium", err_act_fail, B_ERROR }, // T + { 0x3B0D, "Medium destination element full", err_act_fail, B_DEVICE_FULL }, // DT WROM BK + { 0x3B0E, "Medium source element empty", err_act_fail, B_ERROR }, // DT WROM BK + { 0x3B0F, "End of medium reached", err_act_fail, B_ERROR }, // R + { 0x3B11, "Medium magazine not accessible", err_act_fail, B_ERROR }, // DT WROM BK + { 0x3B12, "Medium magazine removed", err_act_fail, B_ERROR }, // DT WROM BK + { 0x3B13, "Medium magazine inserted", err_act_fail, B_ERROR }, // DT WROM BK + { 0x3B14, "Medium magazine locked", err_act_fail, B_ERROR }, // DT WROM BK + { 0x3B15, "Medium magazine unlocked", err_act_fail, B_ERROR }, // DT WROM BK + { 0x3B16, "Mechanical positioning or changer error", err_act_fail, B_ERROR }, // R + { 0x3B17, "Read past end of user object", err_act_fail, B_ERROR }, // F + { 0x3B18, "Element disabled", err_act_fail, B_ERROR }, // M + { 0x3B19, "Element enabled", err_act_fail, B_ERROR }, // M + { 0x3B1A, "Data transfer device removed", err_act_fail, B_ERROR }, // M + { 0x3B1B, "Data transfer device inserted", err_act_fail, B_ERROR }, // M + { 0x3B1C, "Too many logical objects on partition to support operation", err_act_fail, B_ERROR }, // T + { 0x3D00, "Invalid bits in IDENTIFY message", err_act_fail, B_ERROR }, // DTLPWROMAE K + { 0x3E00, "Logical unit has not self-configured yet", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3E01, "Logical unit failure", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3E02, "Timeout on logical unit", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3E03, "Logical unit failed self-test", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3E04, "Logical unit unable to update self-test log", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3F00, "Target operating conditions have changed", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3F01, "Microcode has been changed", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3F02, "Changed operating definition", err_act_fail, B_ERROR }, // DTLPWROM BK + { 0x3F03, "INQUIRY data has changed", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3F04, "Component device attached", err_act_fail, B_ERROR }, // DT WROMAEBK + { 0x3F05, "Device identifier changed", err_act_fail, B_ERROR }, // DT WROMAEBK + { 0x3F06, "Redundancy group created or modified", err_act_fail, B_ERROR }, // DT WROMAEB + { 0x3F07, "Redundancy group deleted", err_act_fail, B_ERROR }, // DT WROMAEB + { 0x3F08, "Spare created or modified", err_act_fail, B_ERROR }, // DT WROMAEB + { 0x3F09, "Spare deleted", err_act_fail, B_ERROR }, // DT WROMAEB + { 0x3F0A, "Volume set created or modified", err_act_fail, B_ERROR }, // DT WROMAEBK + { 0x3F0B, "Volume set deleted", err_act_fail, B_ERROR }, // DT WROMAEBK + { 0x3F0C, "Volume set deassigned", err_act_fail, B_ERROR }, // DT WROMAEBK + { 0x3F0D, "Volume set reassigned", err_act_fail, B_ERROR }, // DT WROMAEBK + { 0x3F0E, "Reported LUNs data has changed", err_act_rescan, B_ERROR }, // DTLPWROMAE + { 0x3F0F, "Echo buffer overwritten", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x3F10, "Medium loadable", err_act_fail, B_ERROR }, // DT WROM B + { 0x3F11, "Medium auxiliary memory accessible", err_act_fail, B_ERROR }, // DT WROM B + { 0x3F12, "iSCSI IP address added", err_act_fail, B_ERROR }, // DTLPWR MAEBK F + { 0x3F13, "iSCSI IP address removed", err_act_fail, B_ERROR }, // DTLPWR MAEBK F + { 0x3F14, "iSCSI IP address changed", err_act_fail, B_ERROR }, // DTLPWR MAEBK F + { 0x3F15, "Inspect referrals sense descriptors", err_act_fail, B_ERROR }, // DTLPWR MAEBK + { 0x4000, "RAM failure", err_act_fail, B_ERROR }, // D + { 0x40ff, "Diagnostic failure on component ID ASQ", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4100, "Data path failure", err_act_fail, B_ERROR }, // D + { 0x4200, "Power-on or self-test failure", err_act_fail, B_ERROR }, // D + { 0x4300, "Message error", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4400, "Internal target failure", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4401, "Persistent reservation information lost", err_act_fail, B_ERROR }, // DT P MAEBKVF + { 0x4471, "ATA device failed set features", err_act_fail, B_ERROR }, // DT B + { 0x4500, "Select or reselect failure", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4600, "Unsuccessful soft reset", err_act_fail, B_ERROR }, // DTLPWROM BK + { 0x4700, "SCSI parity error", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4701, "Data phase CRC error detected", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4702, "SCSI parity error detected during ST data phase", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4703, "Information unit iuCRC error detected", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4704, "Asynchronous information protection error detected", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4705, "Protocol service CRC error", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4706, "PHY test function in progress", err_act_fail, B_ERROR }, // DT MAEBKVF + { 0x477F, "Some commands cleared by iSCSI protocol event", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x4800, "Initiator detected error message received", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4900, "Invalid message error", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4A00, "Command phase error", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4B00, "Data phase error", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4B01, "Invalid target port transfer tag received", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x4B02, "Too much write data", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x4B03, "ACK/NAK timeout", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x4B04, "NAK received", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x4B05, "Data offset error", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x4B06, "Initiator response timeout", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x4B07, "Connection lost", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B08, "Data-in buffer overflow - data buffer size", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B09, "Data-in buffer overflow - data buffer descriptor area", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B0A, "Data-in buffer error", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B0B, "Data-out buffer overflow - data buffer size", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B0C, "Data-out buffer overflow - data buffer descriptor area", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B0D, "Data-out buffer error", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B0E, "PCIe fabric error", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B0F, "PCIe completion timeout", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B10, "PCIe completer abort", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B11, "PCIe poisoned TLP received", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B12, "PCIe eCRC check failed", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B13, "PCIe unsupported request", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B14, "PCIe ACS violation", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4B15, "PCIe TLP prefix blocked", err_act_fail, B_ERROR }, // DT PWROMAEBK F + { 0x4C00, "Logical unit failed self-configuration", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4DFF, "Tagged overlapped commands ASQ", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x4E00, "Overlapped commands attempted", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x5000, "Write append error", err_act_fail, B_ERROR }, // T + { 0x5001, "Write append position error", err_act_fail, B_ERROR }, // T + { 0x5002, "Position error related to timing", err_act_fail, B_ERROR }, // T + { 0x5100, "Erase failure", err_act_fail, B_ERROR }, // T RO + { 0x5101, "Erase failure - incomplete erase operation detected", err_act_fail, B_ERROR }, // R + { 0x5200, "Cartridge fault", err_act_fail, B_ERROR }, // T + { 0x5300, "Media load or eject failed", err_act_fail, B_ERROR }, // DTL WROM BK + { 0x5301, "Unload tape failure", err_act_fail, B_ERROR }, // T + { 0x5302, "Medium removal prevented", err_act_fail, B_ERROR }, // DT WROM BK + { 0x5303, "Medium removal prevented by data transfer element", err_act_fail, B_ERROR }, // M + { 0x5304, "Medium thread or unthread failure", err_act_fail, B_ERROR }, // T + { 0x5305, "Volume identifier invalid", err_act_fail, B_ERROR }, // M + { 0x5306, "Volume identifier missing", err_act_fail, B_ERROR }, // M + { 0x5307, "Duplicate volume identifier", err_act_fail, B_ERROR }, // M + { 0x5308, "Element status unknown", err_act_fail, B_ERROR }, // M + { 0x5400, "SCSI to host system interface failure", err_act_fail, B_ERROR }, // P + { 0x5500, "System resource failure", err_act_fail, B_ERROR }, // P + { 0x5501, "System buffer full", err_act_fail, B_DEVICE_FULL }, // D O BK + { 0x5502, "Insufficient reservation resources", err_act_fail, B_ERROR }, // DTLPWROMAE K + { 0x5503, "Insufficient resources", err_act_fail, B_ERROR }, // DTLPWROMAE K + { 0x5504, "Insufficient registration resources", err_act_fail, B_ERROR }, // DTLPWROMAE K + { 0x5505, "Insufficient access control resources", err_act_fail, B_ERROR }, // DT PWROMAEBK + { 0x5506, "Auxiliary memory out of space", err_act_fail, B_ERROR }, // DT WROM B + { 0x5507, "Quota error", err_act_fail, B_ERROR }, // F + { 0x5508, "Maximum number of supplemental decryption keys exceeded", err_act_fail, B_ERROR }, // T + { 0x5509, "Medium auxiliary memory not accessible", err_act_fail, B_ERROR }, // M + { 0x550A, "Data currently unavailable", err_act_fail, B_ERROR }, // M + { 0x550B, "Insufficient power for operation", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x550C, "Insufficient resources to create ROD", err_act_fail, B_ERROR }, // DT P B + { 0x550D, "Insufficient resources to create ROD token", err_act_fail, B_ERROR }, // DT P B + { 0x5700, "Unable to recover table-of-contents", err_act_fail, B_ERROR }, // R + { 0x5800, "Generation does not exist", err_act_fail, B_ERROR }, // O + { 0x5900, "Updated block read", err_act_fail, B_ERROR }, // O + { 0x5A00, "Operator request or state change input", err_act_fail, B_ERROR }, // DTLPWRO BK + { 0x5A01, "Operator medium removal request", err_act_retry, B_DEV_MEDIA_CHANGE_REQUESTED }, // DT WROM BK + { 0x5A02, "Operator selected write protect", err_act_fail, B_ERROR }, // DT WRO A BK + { 0x5A03, "Operator selected write permit", err_act_fail, B_ERROR }, // DT WRO A BK + { 0x5B00, "Log exception", err_act_fail, B_ERROR }, // DTLPWROM K + { 0x5B01, "Threshold condition met", err_act_fail, B_ERROR }, // DTLPWROM K + { 0x5B02, "Log counter at maximum", err_act_fail, B_ERROR }, // DTLPWROM K + { 0x5B03, "Log list codes exhausted", err_act_fail, B_ERROR }, // DTLPWROM K + { 0x5C00, "RPL status change", err_act_fail, B_ERROR }, // D O + { 0x5C01, "Spindles synchronized", err_act_ok, B_OK }, // D O + { 0x5C02, "Spindles not synchronized", err_act_fail, B_ERROR }, // D O + { 0x5D00, "Failure prediction threshold exceeded", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x5D01, "Media failure prediction threshold exceeded", err_act_fail, B_ERROR }, // R B + { 0x5D02, "Logical unit failure prediction threshold exceeded", err_act_fail, B_ERROR }, // R + { 0x5D03, "Spare area exhaustion prediction threshold exceeded", err_act_fail, B_ERROR }, // R + { 0x5D10, "Hardware impending failure general hard drive failure", err_act_fail, B_ERROR }, // D B + { 0x5D11, "Hardware impending failure drive error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D12, "Hardware impending failure data error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D13, "Hardware impending failure seek error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D14, "Hardware impending failure too many block reassigns", err_act_fail, B_ERROR }, // D B + { 0x5D15, "Hardware impending failure access times too high", err_act_fail, B_ERROR }, // D B + { 0x5D16, "Hardware impending failure start unit times too high", err_act_fail, B_ERROR }, // D B + { 0x5D17, "Hardware impending failure channel parametrics", err_act_fail, B_ERROR }, // D B + { 0x5D18, "Hardware impending failure controller detected", err_act_fail, B_ERROR }, // D B + { 0x5D19, "Hardware impending failure throughput performance", err_act_fail, B_ERROR }, // D B + { 0x5D1A, "Hardware impending failure seek time performance", err_act_fail, B_ERROR }, // D B + { 0x5D1B, "Hardware impending failure spin-up retry count", err_act_fail, B_ERROR }, // D B + { 0x5D1C, "Hardware impending failure drive calibration retry count", err_act_fail, B_ERROR }, // D B + { 0x5D20, "Controller impending failure general hard drive failure", err_act_fail, B_ERROR }, // D B + { 0x5D21, "Controller impending failure drive error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D22, "Controller impending failure data error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D23, "Controller impending failure seek error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D24, "Controller impending failure too many block reassigns", err_act_fail, B_ERROR }, // D B + { 0x5D25, "Controller impending failure access times too high", err_act_fail, B_ERROR }, // D B + { 0x5D26, "Controller impending failure start unit times too high", err_act_fail, B_ERROR }, // D B + { 0x5D27, "Controller impending failure channel parametrics", err_act_fail, B_ERROR }, // D B + { 0x5D28, "Controller impending failure controller detected", err_act_fail, B_ERROR }, // D B + { 0x5D29, "Controller impending failure throughput performance", err_act_fail, B_ERROR }, // D B + { 0x5D2A, "Controller impending failure seek time performance", err_act_fail, B_ERROR }, // D B + { 0x5D2B, "Controller impending failure spin-up retry count", err_act_fail, B_ERROR }, // D B + { 0x5D2C, "Controller impending failure drive calibration retry count", err_act_fail, B_ERROR }, // D B + { 0x5D30, "Data channel impending failure general hard drive failure", err_act_fail, B_ERROR }, // D B + { 0x5D31, "Data channel impending failure drive error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D32, "Data channel impending failure data error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D33, "Data channel impending failure seek error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D34, "Data channel impending failure too many block reassigns", err_act_fail, B_ERROR }, // D B + { 0x5D35, "Data channel impending failure access times too high", err_act_fail, B_ERROR }, // D B + { 0x5D36, "Data channel impending failure start unit times too high", err_act_fail, B_ERROR }, // D B + { 0x5D37, "Data channel impending failure channel parametrics", err_act_fail, B_ERROR }, // D B + { 0x5D38, "Data channel impending failure controller detected", err_act_fail, B_ERROR }, // D B + { 0x5D39, "Data channel impending failure throughput performance", err_act_fail, B_ERROR }, // D B + { 0x5D3A, "Data channel impending failure seek time performance", err_act_fail, B_ERROR }, // D B + { 0x5D3B, "Data channel impending failure spin-up retry count", err_act_fail, B_ERROR }, // D B + { 0x5D3C, "Data channel impending failure drive calibration retry count", err_act_fail, B_ERROR }, // D B + { 0x5D40, "Servo impending failure general hard drive failure", err_act_fail, B_ERROR }, // D B + { 0x5D41, "Servo impending failure drive error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D42, "Servo impending failure data error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D43, "Servo impending failure seek error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D44, "Servo impending failure too many block reassigns", err_act_fail, B_ERROR }, // D B + { 0x5D45, "Servo impending failure access times too high", err_act_fail, B_ERROR }, // D B + { 0x5D46, "Servo impending failure start unit times too high", err_act_fail, B_ERROR }, // D B + { 0x5D47, "Servo impending failure channel parametrics", err_act_fail, B_ERROR }, // D B + { 0x5D48, "Servo impending failure controller detected", err_act_fail, B_ERROR }, // D B + { 0x5D49, "Servo impending failure throughput performance", err_act_fail, B_ERROR }, // D B + { 0x5D4A, "Servo impending failure seek time performance", err_act_fail, B_ERROR }, // D B + { 0x5D4B, "Servo impending failure spin-up retry count", err_act_fail, B_ERROR }, // D B + { 0x5D4C, "Servo impending failure drive calibration retry count", err_act_fail, B_ERROR }, // D B + { 0x5D50, "Spindle impending failure general hard drive failure", err_act_fail, B_ERROR }, // D B + { 0x5D51, "Spindle impending failure drive error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D52, "Spindle impending failure data error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D53, "Spindle impending failure seek error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D54, "Spindle impending failure too many block reassigns", err_act_fail, B_ERROR }, // D B + { 0x5D55, "Spindle impending failure access times too high", err_act_fail, B_ERROR }, // D B + { 0x5D56, "Spindle impending failure start unit times too high", err_act_fail, B_ERROR }, // D B + { 0x5D57, "Spindle impending failure channel parametrics", err_act_fail, B_ERROR }, // D B + { 0x5D58, "Spindle impending failure controller detected", err_act_fail, B_ERROR }, // D B + { 0x5D59, "Spindle impending failure throughput performance", err_act_fail, B_ERROR }, // D B + { 0x5D5A, "Spindle impending failure seek time performance", err_act_fail, B_ERROR }, // D B + { 0x5D5B, "Spindle impending failure spin-up retry count", err_act_fail, B_ERROR }, // D B + { 0x5D5C, "Spindle impending failure drive calibration retry count", err_act_fail, B_ERROR }, // D B + { 0x5D60, "Firmware impending failure general hard drive failure", err_act_fail, B_ERROR }, // D B + { 0x5D61, "Firmware impending failure drive error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D62, "Firmware impending failure data error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D63, "Firmware impending failure seek error rate too high", err_act_fail, B_ERROR }, // D B + { 0x5D64, "Firmware impending failure too many block reassigns", err_act_fail, B_ERROR }, // D B + { 0x5D65, "Firmware impending failure access times too high", err_act_fail, B_ERROR }, // D B + { 0x5D66, "Firmware impending failure start unit times too high", err_act_fail, B_ERROR }, // D B + { 0x5D67, "Firmware impending failure channel parametrics", err_act_fail, B_ERROR }, // D B + { 0x5D68, "Firmware impending failure controller detected", err_act_fail, B_ERROR }, // D B + { 0x5D69, "Firmware impending failure throughput performance", err_act_fail, B_ERROR }, // D B + { 0x5D6A, "Firmware impending failure seek time performance", err_act_fail, B_ERROR }, // D B + { 0x5D6B, "Firmware impending failure spin-up retry count", err_act_fail, B_ERROR }, // D B + { 0x5D6C, "Firmware impending failure drive calibration retry count", err_act_fail, B_ERROR }, // D B + { 0x5DFF, "Failure prediction threshold exceeded (false)", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x5E00, "Low power condition on", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x5E01, "Idle condition activated by timer", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x5E02, "Standby condition activated by timer", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x5E03, "Idle condition activated by command", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x5E04, "Standby condition activated by command", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x5E05, "Idle-B condition activated by timer", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x5E06, "Idle-B condition activated by command", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x5E07, "Idle-C condition activated by timer", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x5E08, "Idle-C condition activated by command", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x5E09, "Standby-Y condition activated by timer", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x5E0A, "Standby-Y condition activated by command", err_act_fail, B_ERROR }, // DTLPWRO A K + { 0x5E41, "Power state change to active", err_act_fail, B_ERROR }, // B + { 0x5E42, "Power state change to idle", err_act_fail, B_ERROR }, // B + { 0x5E43, "Power state change to standby", err_act_fail, B_ERROR }, // B + { 0x5E45, "Power state change to sleep", err_act_fail, B_ERROR }, // B + { 0x5E47, "Power state change to device control", err_act_fail, B_ERROR }, // BK + { 0x6000, "Lamp failure", err_act_fail, B_ERROR }, // + { 0x6100, "Video acquisition error", err_act_fail, B_ERROR }, // + { 0x6101, "Unable to acquire video", err_act_fail, B_ERROR }, // + { 0x6102, "Out of focus", err_act_fail, B_ERROR }, // + { 0x6200, "Scan head positioning error", err_act_fail, B_ERROR }, // + { 0x6300, "End of user area encountered on this track", err_act_fail, B_ERROR }, // R + { 0x6301, "Packet does not fit in available space", err_act_fail, B_DEVICE_FULL }, // R + { 0x6400, "Illegal mode for this track", err_act_fail, B_DEV_NOT_READY }, // R + { 0x6401, "Invalid packet size", err_act_fail, B_ERROR }, // R + { 0x6500, "Voltage fault", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x6600, "Automatic document feeder cover up", err_act_fail, B_ERROR }, // + { 0x6601, "Automatic document feeder lift up", err_act_fail, B_ERROR }, // + { 0x6602, "Document jam in automatic document feeder", err_act_fail, B_ERROR }, // + { 0x6603, "Document miss feed automatic in document feeder", err_act_fail, B_ERROR }, // + { 0x6700, "Configuration failure", err_act_fail, B_ERROR }, // A + { 0x6701, "Configuration of incapable logical units failed", err_act_fail, B_ERROR }, // A + { 0x6702, "Add logical unit failed", err_act_fail, B_ERROR }, // A + { 0x6703, "Modification of logical unit failed", err_act_fail, B_ERROR }, // A + { 0x6704, "Exchange of logical unit failed", err_act_fail, B_ERROR }, // A + { 0x6705, "Remove of logical unit failed", err_act_fail, B_ERROR }, // A + { 0x6706, "Attachment of logical unit failed", err_act_fail, B_ERROR }, // A + { 0x6707, "Creation of logical unit failed", err_act_fail, B_ERROR }, // A + { 0x6708, "Assign failure occurred", err_act_fail, B_ERROR }, // A + { 0x6709, "Multiply assigned logical unit", err_act_fail, B_ERROR }, // A + { 0x670A, "Set target port groups command failed", err_act_fail, B_ERROR }, // DTLPWROMAEBKVF + { 0x670B, "ATA device feature not enabled", err_act_fail, B_ERROR }, // DT B + { 0x6800, "Logical unit not configured", err_act_fail, B_ERROR }, // A + { 0x6801, "Subsidiary logical unit not configured", err_act_fail, B_ERROR }, // D + { 0x6900, "Data loss on logical unit", err_act_fail, B_ERROR }, // A + { 0x6901, "Multiple logical unit failures", err_act_fail, B_ERROR }, // A + { 0x6902, "Parity/data mismatch", err_act_fail, B_ERROR }, // A + { 0x6A00, "Informational, refer to log", err_act_fail, B_ERROR }, // A + { 0x6B00, "State change has occurred", err_act_fail, B_ERROR }, // A + { 0x6B01, "Redundancy level got better", err_act_fail, B_ERROR }, // A + { 0x6B02, "Redundancy level got worse", err_act_fail, B_ERROR }, // A + { 0x6C00, "Rebuild failure occurred", err_act_fail, B_ERROR }, // A + { 0x6D00, "Recalculate failure occurred", err_act_fail, B_ERROR }, // A + { 0x6E00, "Command to logical unit failed", err_act_fail, B_ERROR }, // A + { 0x6F00, "Copy protection key exchange failure - authentication failure", err_act_fail, B_ERROR }, // R + { 0x6F01, "Copy protection key exchange failure - key not present", err_act_fail, B_ERROR }, // R + { 0x6F02, "Copy protection key exchange failure - key not established", err_act_fail, B_ERROR }, // R + { 0x6F03, "Read of scrambled sector without authentication", err_act_fail, B_ERROR }, // R + { 0x6F04, "Media region code is mismatched to logical unit region", err_act_fail, B_ERROR }, // R + { 0x6F05, "Drive region must be permanent/region reset count error", err_act_fail, B_ERROR }, // R + { 0x6F06, "Insufficient block count for binding NONCE recording", err_act_fail, B_ERROR }, // R + { 0x6F07, "Conflict in binding nonce recording", err_act_fail, B_ERROR }, // R + { 0x70FF, "Decompression exception short algorithm id ASQ", err_act_fail, B_ERROR }, // T + { 0x7100, "Decompression exception long algorithm id", err_act_fail, B_ERROR }, // T + { 0x7200, "Session fixation error", err_act_fail, B_ERROR }, // R + { 0x7201, "Session fixation error writing lead-in", err_act_fail, B_ERROR }, // R + { 0x7202, "Session fixation error writing lead-out", err_act_fail, B_ERROR }, // R + { 0x7203, "Session fixation error - incomplete track in session", err_act_fail, B_ERROR }, // R + { 0x7204, "Empty or partially written reserved track", err_act_fail, B_ERROR }, // R + { 0x7205, "No more track reservations allowed", err_act_fail, B_ERROR }, // R + { 0x7206, "RMZ extension is not allowed", err_act_fail, B_ERROR }, // R + { 0x7207, "No more test zone extensions are allowed", err_act_fail, B_ERROR }, // R + { 0x7300, "CD control error", err_act_fail, B_ERROR }, // R + { 0x7301, "Power calibration area almost full", err_act_fail, B_ERROR }, // R + { 0x7302, "Power calibration area is full", err_act_fail, B_DEVICE_FULL }, // R + { 0x7303, "Power calibration area error", err_act_fail, B_ERROR }, // R + { 0x7304, "Program memory area update failure", err_act_fail, B_ERROR }, // R + { 0x7305, "Program memory area is full", err_act_fail, B_ERROR }, // R + { 0x7306, "RMA/PMA is almost full", err_act_fail, B_ERROR }, // R + { 0x7310, "Current power calibration area almost full", err_act_fail, B_ERROR }, // R + { 0x7311, "Current power calibration area is full", err_act_fail, B_ERROR }, // R + { 0x7317, "RDZ is full", err_act_fail, B_ERROR }, // R + { 0x7400, "Security error", err_act_fail, B_ERROR }, // T + { 0x7401, "Unable to decrypt data", err_act_fail, B_ERROR }, // T + { 0x7402, "Unencrypted data encountered while decrypting", err_act_fail, B_ERROR }, // T + { 0x7403, "Incorrect data encryption key", err_act_fail, B_ERROR }, // T + { 0x7404, "Cryptographic integrity validation failed", err_act_fail, B_ERROR }, // T + { 0x7405, "Error decrypting data", err_act_fail, B_ERROR }, // T + { 0x7406, "Unknown signature verification key", err_act_fail, B_ERROR }, // T + { 0x7407, "Encryption parameters not useable", err_act_fail, B_ERROR }, // T + { 0x7408, "Digital signature validation failure", err_act_fail, B_ERROR }, // DT R M E VF + { 0x7409, "Encryption mode mismatch on read", err_act_fail, B_ERROR }, // T + { 0x740A, "Encrypted block not raw read enabled", err_act_fail, B_ERROR }, // T + { 0x740B, "Incorrect encryption parameters", err_act_fail, B_ERROR }, // T + { 0x740C, "Unable to decrypt parameter list", err_act_fail, B_ERROR }, // DT R MAEBKV + { 0x740D, "Encryption algorithm disabled", err_act_fail, B_ERROR }, // T + { 0x7410, "SA creation parameter value invalid", err_act_fail, B_ERROR }, // DT R MAEBKV + { 0x7411, "SA creation parameter value rejected", err_act_fail, B_ERROR }, // DT R MAEBKV + { 0x7412, "Invalid SA usage", err_act_fail, B_ERROR }, // DT R MAEBKV + { 0x7421, "Data encryption configuration prevented", err_act_fail, B_ERROR }, // T + { 0x7430, "SA creation parameter not supported", err_act_fail, B_ERROR }, // DT R MAEBKV + { 0x7440, "Authentication failed", err_act_fail, B_ERROR }, // DT R MAEBKV + { 0x7461, "External data encryption key manager access error", err_act_fail, B_ERROR }, // V + { 0x7462, "External data encryption key manager error", err_act_fail, B_ERROR }, // V + { 0x7463, "External data encryption key not found", err_act_fail, B_ERROR }, // V + { 0x7464, "External data encryption request not authorized", err_act_fail, B_ERROR }, // V + { 0x746E, "External data encryption control timeout", err_act_fail, B_ERROR }, // T + { 0x746F, "External data encryption control error", err_act_fail, B_ERROR }, // T + { 0x7471, "Logical unit access not authorized", err_act_fail, B_ERROR }, // DT R M E V + { 0x7479, "Security conflict in translated device", err_act_fail, B_ERROR }, // D +}; + +// Use these values for loop control during searching: +#define SCSI_SENSE_KEY_TABLE_LEN (sizeof(sSCSISenseKeyTable)/sizeof(scsi_sense_key_table)) +#define SCSI_SENSE_ASC_ASCQ_TABLE_LEN (sizeof(sSCSISenseAscTable)/sizeof(scsi_sense_asc_table)) + + +status_t +scsi_get_sense_key_info(uint8 key, const char **label, err_act *action, status_t *error) +{ + int i; + for (i = 0; i < (int)SCSI_SENSE_KEY_TABLE_LEN; i++) { + if (sSCSISenseKeyTable[i].key == key) { + *label = sSCSISenseKeyTable[i].label; + *action = sSCSISenseKeyTable[i].action; + *error = sSCSISenseKeyTable[i].err; + return B_OK; + } + } + *label = NULL; + return B_BAD_VALUE; +} + + +status_t +scsi_get_sense_asc_info(uint16 asc_asq, const char **label, err_act *action, status_t *error) +{ + int i; + for (i = 0; i < (int)SCSI_SENSE_ASC_ASCQ_TABLE_LEN; i++) { + if (sSCSISenseAscTable[i].asc_ascq == asc_asq) { + *label = sSCSISenseAscTable[i].label; + *action = sSCSISenseAscTable[i].action; + *error = sSCSISenseAscTable[i].err; + return B_OK; + } + } + *label = NULL; + return B_BAD_VALUE; +} + + + + + + diff --git a/src/add-ons/kernel/drivers/disk/usb/usb_disk/Jamfile b/src/add-ons/kernel/drivers/disk/usb/usb_disk/Jamfile index 862e3678a9..995055abb2 100644 --- a/src/add-ons/kernel/drivers/disk/usb/usb_disk/Jamfile +++ b/src/add-ons/kernel/drivers/disk/usb/usb_disk/Jamfile @@ -1,7 +1,7 @@ SubDir HAIKU_TOP src add-ons kernel drivers disk usb usb_disk ; SubDirSysHdrs $(HAIKU_TOP) src add-ons kernel bus_managers usb ; -UsePrivateHeaders kernel ; +UsePrivateHeaders drivers kernel ; KernelAddon usb_disk : usb_disk.cpp diff --git a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp index ff03f98071..6c874f355b 100644 --- a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp @@ -18,6 +18,7 @@ #include +#include "scsi_sense.h" #include "usb_disk_scsi.h" @@ -136,11 +137,11 @@ status_t usb_disk_receive_csw(disk_device *device, status_t usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength, uint32 logicalBlockAddress, uint16 transferLength, void *data, size_t *dataLength, - bool directionIn); + bool directionIn, err_act *action = NULL); -status_t usb_disk_request_sense(device_lun *lun); +status_t usb_disk_request_sense(device_lun *lun, err_act *action); status_t usb_disk_mode_sense(device_lun *lun); -status_t usb_disk_test_unit_ready(device_lun *lun); +status_t usb_disk_test_unit_ready(device_lun *lun, err_act *action = NULL); status_t usb_disk_inquiry(device_lun *lun); status_t usb_disk_reset_capacity(device_lun *lun); status_t usb_disk_update_capacity(device_lun *lun); @@ -265,7 +266,7 @@ usb_disk_receive_csw(disk_device *device, command_status_wrapper *status) status_t usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength, uint32 logicalBlockAddress, uint16 transferLength, void *data, - size_t *dataLength, bool directionIn) + size_t *dataLength, bool directionIn, err_act *_action) { TRACE("operation: lun: %u; op: %u; oplen: %u; lba: %" B_PRIu32 "; tlen: %u; data: %p; dlen: %p (%lu); in: %c\n", @@ -407,7 +408,7 @@ usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength, " failed at the SCSI level\n", operation); } - result = usb_disk_request_sense(lun); + result = usb_disk_request_sense(lun, _action); return result == B_OK ? B_ERROR : result; } } @@ -437,7 +438,7 @@ usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength, status_t -usb_disk_request_sense(device_lun *lun) +usb_disk_request_sense(device_lun *lun, err_act *_action) { size_t dataLength = sizeof(scsi_request_sense_6_parameter); scsi_request_sense_6_parameter parameter; @@ -449,56 +450,42 @@ usb_disk_request_sense(device_lun *lun) return result; } + const char *label = NULL; + err_act action = err_act_fail; + status_t status = B_ERROR; + scsi_get_sense_asc_info((parameter.additional_sense_code << 8) + | parameter.additional_sense_code_qualifier, &label, &action, + &status); + if (parameter.sense_key > SCSI_SENSE_KEY_NOT_READY && parameter.sense_key != SCSI_SENSE_KEY_UNIT_ATTENTION) { TRACE_ALWAYS("request_sense: key: 0x%02x; asc: 0x%02x; ascq: " - "0x%02x;\n", parameter.sense_key, parameter.additional_sense_code, - parameter.additional_sense_code_qualifier); + "0x%02x; %s\n", parameter.sense_key, parameter.additional_sense_code, + parameter.additional_sense_code_qualifier, + label ? label : "(unknown)"); } - switch (parameter.sense_key) { - case SCSI_SENSE_KEY_NO_SENSE: - case SCSI_SENSE_KEY_RECOVERED_ERROR: - return B_OK; - - case SCSI_SENSE_KEY_HARDWARE_ERROR: - case SCSI_SENSE_KEY_MEDIUM_ERROR: - TRACE_ALWAYS("request_sense: media or hardware error\n"); - return B_DEV_UNREADABLE; - - case SCSI_SENSE_KEY_ILLEGAL_REQUEST: - TRACE_ALWAYS("request_sense: illegal request\n"); - return B_DEV_INVALID_IOCTL; - - case SCSI_SENSE_KEY_UNIT_ATTENTION: - if (parameter.additional_sense_code - != SCSI_ASC_MEDIUM_NOT_PRESENT) { - TRACE_ALWAYS("request_sense: media changed\n"); - lun->media_changed = true; - lun->media_present = true; - - return B_DEV_MEDIA_CHANGED; - } - // fall through - - case SCSI_SENSE_KEY_NOT_READY: - TRACE("request_sense: device not ready (asc 0x%02x ascq 0x%02x)\n", - parameter.additional_sense_code, - parameter.additional_sense_code_qualifier); - lun->media_present = false; - usb_disk_reset_capacity(lun); - return B_DEV_NOT_READY; - - case SCSI_SENSE_KEY_DATA_PROTECT: - TRACE_ALWAYS("request_sense: write protected\n"); - return B_READ_ONLY_DEVICE; - - case SCSI_SENSE_KEY_ABORTED_COMMAND: - TRACE_ALWAYS("request_sense: command aborted\n"); - return B_CANCELED; + if ((parameter.additional_sense_code == 0 + && parameter.additional_sense_code_qualifier == 0) + || label == NULL) { + scsi_get_sense_key_info(parameter.sense_key, &label, &action, &status); } - return B_ERROR; + if (status == B_DEV_MEDIA_CHANGED) { + lun->media_changed = true; + lun->media_present = true; + } else if (parameter.sense_key == SCSI_SENSE_KEY_UNIT_ATTENTION + && status != B_DEV_NO_MEDIA) { + lun->media_present = true; + } else if (status == B_DEV_NOT_READY) { + lun->media_present = false; + usb_disk_reset_capacity(lun); + } + + if (_action != NULL) + *_action = action; + + return status; } @@ -524,7 +511,7 @@ usb_disk_mode_sense(device_lun *lun) status_t -usb_disk_test_unit_ready(device_lun *lun) +usb_disk_test_unit_ready(device_lun *lun, err_act *_action) { // if unsupported we assume the unit is fixed and therefore always ok if (!lun->device->tur_supported) @@ -533,10 +520,10 @@ usb_disk_test_unit_ready(device_lun *lun) status_t result; if (lun->device->is_atapi) { result = usb_disk_operation(lun, SCSI_START_STOP_UNIT_6, 6, 0, 1, - NULL, NULL, false); + NULL, NULL, false, _action); } else { result = usb_disk_operation(lun, SCSI_TEST_UNIT_READY_6, 6, 0, 0, - NULL, NULL, true); + NULL, NULL, true, _action); } if (result == B_DEV_INVALID_IOCTL) { @@ -554,11 +541,14 @@ usb_disk_inquiry(device_lun *lun) size_t dataLength = sizeof(scsi_inquiry_6_parameter); scsi_inquiry_6_parameter parameter; status_t result = B_ERROR; + err_act action = err_act_ok; for (uint32 tries = 0; tries < 3; tries++) { result = usb_disk_operation(lun, SCSI_INQUIRY_6, 6, 0, dataLength, - ¶meter, &dataLength, true); - if (result == B_OK) + ¶meter, &dataLength, true, &action); + if (result == B_OK || (action != err_act_retry + && action != err_act_many_retries)) { break; + } } if (result != B_OK) { TRACE_ALWAYS("getting inquiry data failed: %s\n", strerror(result)); @@ -612,6 +602,7 @@ usb_disk_update_capacity(device_lun *lun) size_t dataLength = sizeof(scsi_read_capacity_10_parameter); scsi_read_capacity_10_parameter parameter; status_t result = B_ERROR; + err_act action = err_act_ok; // Retry reading the capacity up to three times. The first try might only // yield a unit attention telling us that the device or media status @@ -620,9 +611,11 @@ usb_disk_update_capacity(device_lun *lun) // reads. for (int32 i = 0; i < 3; i++) { result = usb_disk_operation(lun, SCSI_READ_CAPACITY_10, 10, 0, 0, - ¶meter, &dataLength, true); - if (result == B_OK) + ¶meter, &dataLength, true, &action); + if (result == B_OK || (action != err_act_retry + && action != err_act_many_retries)) { break; + } } if (result != B_OK) { @@ -801,10 +794,11 @@ usb_disk_device_added(usb_device newDevice, void **cookie) // initialize this lun result = usb_disk_inquiry(lun); + err_act action = err_act_ok; for (uint32 tries = 0; tries < 8; tries++) { TRACE("usb lun %"B_PRIu8" inquiry attempt %"B_PRIu32" begin\n", i, tries); - status_t ready = usb_disk_test_unit_ready(lun); + status_t ready = usb_disk_test_unit_ready(lun, &action); if (ready == B_OK || ready == B_DEV_NO_MEDIA) { if (lun->device_type == B_CD) lun->write_protected = true; @@ -821,7 +815,8 @@ usb_disk_device_added(usb_device newDevice, void **cookie) } TRACE("usb lun %"B_PRIu8" inquiry attempt %"B_PRIu32" failed\n", i, tries); - + if (action != err_act_retry && action != err_act_many_retries) + break; bigtime_t snoozeTime = 1000000 * tries; TRACE("snoozing %"B_PRIu64" microseconds for usb lun\n", snoozeTime); @@ -1095,7 +1090,17 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) switch (op) { case B_GET_MEDIA_STATUS: { - *(status_t *)buffer = usb_disk_test_unit_ready(lun); + err_act action = err_act_ok; + for (uint32 tries = 0; tries < 3; tries++) { + status_t ready = usb_disk_test_unit_ready(lun, &action); + if (ready == B_OK || ready == B_DEV_NO_MEDIA + || (action != err_act_retry + && action != err_act_many_retries)) { + *(status_t *)buffer = ready; + break; + } + snooze(500000); + } TRACE("B_GET_MEDIA_STATUS: 0x%08" B_PRIx32 "\n", *(status_t *)buffer); result = B_OK; From 18ad64f2272bb01767870a2f05f7a94065769418 Mon Sep 17 00:00:00 2001 From: Niels Sascha Reedijk Date: Sat, 21 Sep 2013 06:13:23 +0200 Subject: [PATCH 128/137] Update translations from Pootle --- data/catalogs/apps/icon-o-matic/fr.catkeys | 4 +++- data/catalogs/apps/webpositive/ru.catkeys | 2 +- data/catalogs/preferences/screensaver/sv.catkeys | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/data/catalogs/apps/icon-o-matic/fr.catkeys b/data/catalogs/apps/icon-o-matic/fr.catkeys index 806631486e..cc263be4e0 100644 --- a/data/catalogs/apps/icon-o-matic/fr.catkeys +++ b/data/catalogs/apps/icon-o-matic/fr.catkeys @@ -1,4 +1,4 @@ -1 french x-vnd.haiku-icon_o_matic 806315965 +1 french x-vnd.haiku-icon_o_matic 2058853918 Select All Icon-O-Matic-PathManipulator Sélectionner tout Add Style Icon-O-Matic-AddStylesCmd Ajouter un style Color (#%02x%02x%02x) Style name after dropping a color Couleur (#%02x%02x%02x) @@ -139,6 +139,7 @@ Save image Icon-O-Matic-SavePanel Enregistrer l'image Add Styles Icon-O-Matic-AddStylesCmd Ajouter des styles Remove Control Points Icon-O-Matic-RemovePointsCmd Enlever les points de contrôle Format Icon-O-Matic-SavePanel Format +Add rect Icon-O-Matic-PathsList Ajouter un rectangle Edit Icon-O-Matic-Menus Éditer Duplicate Icon-O-Matic-StylesList Dupliquer too big Icon-O-Matic-StyledTextImport trop grand @@ -161,6 +162,7 @@ Split Control Point Icon-O-Matic-SplitPointsCmd Diviser le point de contrôle Open… Icon-O-Matic-Menu-File Ouvrir… Color (#%02x%02x%02x) Icon-O-Matic-StyledTextImport Couleur (#%02x%02x%02x) Edit Gradient Icon-O-Matic-SetGradientCmd Éditer le dégadé +Clean Up Path Icon-O-Matic-CleanUpPathCmd Nettoyer le chemin Rounding Icon-O-Matic-PropertyNames Arrondi Remove Shapes Icon-O-Matic-RemoveShapesCmd Enlever les formes Clean up Icon-O-Matic-PathsList Nettoyer diff --git a/data/catalogs/apps/webpositive/ru.catkeys b/data/catalogs/apps/webpositive/ru.catkeys index b9b28e50a1..926f1b4e07 100644 --- a/data/catalogs/apps/webpositive/ru.catkeys +++ b/data/catalogs/apps/webpositive/ru.catkeys @@ -77,7 +77,7 @@ Bookmark info WebPositive Window Информация о закладке Size: Font Selection view Размер: Show tabs if only one page is open Settings Window Всегда показывать панель вкладок, даже если открыта только одна вкладка. About WebPositive Window О программе -Finish: Download Window Finishing time Завершиться в: +Finish: Download Window Finishing time Завершится в: Fonts Settings Window Шрифты OK Download Window OK Page source error WebPositive Window Ошибка в исходном коде страницы diff --git a/data/catalogs/preferences/screensaver/sv.catkeys b/data/catalogs/preferences/screensaver/sv.catkeys index 62006e74a4..d020cbdde3 100644 --- a/data/catalogs/preferences/screensaver/sv.catkeys +++ b/data/catalogs/preferences/screensaver/sv.catkeys @@ -1,4 +1,4 @@ -1 swedish x-vnd.Haiku-ScreenSaver 3630119516 +1 swedish x-vnd.Haiku-ScreenSaver 232492478 Could not load screen saver ScreenSaver Kunde inte läsa in skärmsläckaren 30 seconds ScreenSaver 30 sekunder Start screensaver ScreenSaver Starta skärmsläckare @@ -11,7 +11,9 @@ Display Power Management Signaling not available ScreenSaver Stöd för att sä ScreenSaver System name Skärmsläckare Test ScreenSaver Testa General ScreenSaver Allmänt +Fade now when mouse is here ScreenSaver Avta nu när musen är här Enable screensaver ScreenSaver Aktivera skärmsläckare +Don't fade when mouse is here ScreenSaver Avta inte nu när musen är här Cancel ScreenSaver Avbryt Turn off screen ScreenSaver Stäng av skärmen No options available ScreenSaver Inga alternativ tillgängliga From afaa6ed4b37c519afd3f593509fd490082d7b8d2 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Sat, 21 Sep 2013 21:52:13 +0200 Subject: [PATCH 129/137] x86[_64]: Randomize initial stack pointer on alternative signal stacks If the alternate signal stack is used randomize the initial stack pointer in the same way it is randomized on "normal" thread stacks. Also, update MINSIGSTKSZ value so that regardless of where the new stack pointer points to there is at least 4k of stack left. --- headers/posix/signal.h | 2 +- src/system/kernel/arch/x86/32/thread.cpp | 21 +++++++++++---------- src/system/kernel/arch/x86/64/thread.cpp | 21 +++++++++++---------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/headers/posix/signal.h b/headers/posix/signal.h index 7415cfe99c..d56cf2edfa 100644 --- a/headers/posix/signal.h +++ b/headers/posix/signal.h @@ -95,7 +95,7 @@ struct sigaction { #define SS_ONSTACK 0x1 #define SS_DISABLE 0x2 -#define MINSIGSTKSZ 4096 +#define MINSIGSTKSZ 8192 #define SIGSTKSZ 16384 /* for signals using an alternate stack */ diff --git a/src/system/kernel/arch/x86/32/thread.cpp b/src/system/kernel/arch/x86/32/thread.cpp index 66465c2951..7bed6a0f4d 100644 --- a/src/system/kernel/arch/x86/32/thread.cpp +++ b/src/system/kernel/arch/x86/32/thread.cpp @@ -110,6 +110,15 @@ x86_set_tls_context(Thread *thread) } +static addr_t +arch_randomize_stack_pointer(addr_t value) +{ + STATIC_ASSERT(MAX_RANDOM_VALUE >= B_PAGE_SIZE - 1); + value -= random_value() & (B_PAGE_SIZE - 1); + return value & ~addr_t(0xf); +} + + static uint8* get_signal_stack(Thread* thread, struct iframe* frame, struct sigaction* action) { @@ -119,7 +128,8 @@ get_signal_stack(Thread* thread, struct iframe* frame, struct sigaction* action) && (frame->user_sp < thread->signal_stack_base || frame->user_sp >= thread->signal_stack_base + thread->signal_stack_size)) { - return (uint8*)(thread->signal_stack_base + thread->signal_stack_size); + addr_t stackTop = thread->signal_stack_base + thread->signal_stack_size; + return (uint8*)arch_randomize_stack_pointer(stackTop); } return (uint8*)frame->user_sp; @@ -202,15 +212,6 @@ arch_thread_dump_info(void *info) } -static addr_t -arch_randomize_stack_pointer(addr_t value) -{ - STATIC_ASSERT(MAX_RANDOM_VALUE >= B_PAGE_SIZE - 1); - value -= random_value() & (B_PAGE_SIZE - 1); - return value & ~addr_t(0xf); -} - - /*! Sets up initial thread context and enters user space */ status_t diff --git a/src/system/kernel/arch/x86/64/thread.cpp b/src/system/kernel/arch/x86/64/thread.cpp index e1a337fe3c..59db5028e4 100644 --- a/src/system/kernel/arch/x86/64/thread.cpp +++ b/src/system/kernel/arch/x86/64/thread.cpp @@ -95,6 +95,15 @@ x86_set_tls_context(Thread* thread) } +static addr_t +arch_randomize_stack_pointer(addr_t value) +{ + STATIC_ASSERT(MAX_RANDOM_VALUE >= B_PAGE_SIZE - 1); + value -= random_value() & (B_PAGE_SIZE - 1); + return value & ~addr_t(0xf); +} + + static uint8* get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action) { @@ -104,7 +113,8 @@ get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action) && (frame->user_sp < thread->signal_stack_base || frame->user_sp >= thread->signal_stack_base + thread->signal_stack_size)) { - return (uint8*)(thread->signal_stack_base + thread->signal_stack_size); + addr_t stackTop = thread->signal_stack_base + thread->signal_stack_size; + return (uint8*)arch_randomize_stack_pointer(stackTop); } // We are going to use the stack that we are already on. We must not touch @@ -198,15 +208,6 @@ arch_thread_dump_info(void* info) } -static addr_t -arch_randomize_stack_pointer(addr_t value) -{ - STATIC_ASSERT(MAX_RANDOM_VALUE >= B_PAGE_SIZE - 1); - value -= random_value() & (B_PAGE_SIZE - 1); - return value & ~addr_t(0xf); -} - - /*! Sets up initial thread context and enters user space */ status_t From 4c78b73b8a5411d19320e31510654e42815178db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sun, 22 Sep 2013 23:08:24 +0200 Subject: [PATCH 130/137] ps2: added initial support for elantech pads. * also added a license to ps2_alps.h * added ps2_dev_sliced_command() * moved some ps2 commands definitions to ps2_defs.h --- src/add-ons/kernel/bus_managers/ps2/Jamfile | 1 + .../kernel/bus_managers/ps2/ps2_alps.cpp | 50 +- .../kernel/bus_managers/ps2/ps2_alps.h | 7 + .../kernel/bus_managers/ps2/ps2_common.cpp | 7 +- .../kernel/bus_managers/ps2/ps2_common.h | 1 + .../kernel/bus_managers/ps2/ps2_defs.h | 8 + .../kernel/bus_managers/ps2/ps2_dev.cpp | 31 +- src/add-ons/kernel/bus_managers/ps2/ps2_dev.h | 6 +- .../kernel/bus_managers/ps2/ps2_elantech.cpp | 801 ++++++++++++++++++ .../kernel/bus_managers/ps2/ps2_elantech.h | 59 ++ 10 files changed, 934 insertions(+), 37 deletions(-) create mode 100644 src/add-ons/kernel/bus_managers/ps2/ps2_elantech.cpp create mode 100644 src/add-ons/kernel/bus_managers/ps2/ps2_elantech.h diff --git a/src/add-ons/kernel/bus_managers/ps2/Jamfile b/src/add-ons/kernel/bus_managers/ps2/Jamfile index d2abde2182..c5d6817669 100644 --- a/src/add-ons/kernel/bus_managers/ps2/Jamfile +++ b/src/add-ons/kernel/bus_managers/ps2/Jamfile @@ -8,6 +8,7 @@ KernelAddon ps2 : ps2_alps.cpp ps2_common.cpp ps2_dev.cpp + ps2_elantech.cpp ps2_keyboard.cpp ps2_module.cpp ps2_standard_mouse.cpp diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_alps.cpp b/src/add-ons/kernel/bus_managers/ps2/ps2_alps.cpp index 70625df8dd..31affc9e58 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_alps.cpp +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_alps.cpp @@ -67,8 +67,8 @@ public: private: bool fFired; uint8 fLastPackage[PS2_PACKET_ALPS]; - timer fEventTimer; - alps_cookie* fCookie; + timer fEventTimer; + alps_cookie* fCookie; }; @@ -112,7 +112,7 @@ typedef struct alps_model_info { static const struct alps_model_info gALPSModelInfos[] = { {{0x32, 0x02, 0x14}, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT}, - // Toshiba Salellite Pro M10 + // Toshiba Salellite Pro M10 // {{0x33, 0x02, 0x0a}, 0x88, 0xf8, ALPS_OLDPROTO}, // UMAX-530T {{0x53, 0x02, 0x0a}, 0xf8, 0xf8, 0}, @@ -155,15 +155,6 @@ static const struct alps_model_info gALPSModelInfos[] = { static alps_model_info* sFoundModel = NULL; -#define PS2_MOUSE_CMD_SET_SCALE11 0xe6 -#define PS2_MOUSE_CMD_SET_SCALE21 0xe7 -#define PS2_MOUSE_CMD_SET_RES 0xe8 -#define PS2_MOUSE_CMD_GET_INFO 0xe9 -#define PS2_MOUSE_CMD_SET_STREAM 0xea -#define PS2_MOUSE_CMD_SET_POLL 0xf0 -#define PS2_MOUSE_CMD_SET_RATE 0xf3 - - // touchpad proportions #define EDGE_MOTION_WIDTH 55 // increase the touchpad size a little bit @@ -279,16 +270,16 @@ probe_alps(ps2_dev* dev) TRACE("ALPS: probe\n"); val[0] = 0; - if (ps2_dev_command(dev, PS2_MOUSE_CMD_SET_RES, val, 1, NULL, 0) != B_OK - || ps2_dev_command(dev, PS2_MOUSE_CMD_SET_SCALE11, NULL, 0, NULL, 0) + if (ps2_dev_command(dev, PS2_CMD_MOUSE_SET_RES, val, 1, NULL, 0) != B_OK + || ps2_dev_command(dev, PS2_CMD_MOUSE_SET_SCALE11, NULL, 0, NULL, 0) != B_OK - || ps2_dev_command(dev, PS2_MOUSE_CMD_SET_SCALE11, NULL, 0, NULL, 0) + || ps2_dev_command(dev, PS2_CMD_MOUSE_SET_SCALE11, NULL, 0, NULL, 0) != B_OK - || ps2_dev_command(dev, PS2_MOUSE_CMD_SET_SCALE11, NULL, 0, NULL, 0) + || ps2_dev_command(dev, PS2_CMD_MOUSE_SET_SCALE11, NULL, 0, NULL, 0) != B_OK) return B_ERROR; - if (ps2_dev_command(dev, PS2_MOUSE_CMD_GET_INFO, NULL, 0, val, 3) + if (ps2_dev_command(dev, PS2_CMD_MOUSE_GET_INFO, NULL, 0, val, 3) != B_OK) return B_ERROR; @@ -296,16 +287,16 @@ probe_alps(ps2_dev* dev) return B_ERROR; val[0] = 0; - if (ps2_dev_command(dev, PS2_MOUSE_CMD_SET_RES, val, 1, NULL, 0) != B_OK - || ps2_dev_command(dev, PS2_MOUSE_CMD_SET_SCALE21, NULL, 0, NULL, 0) + if (ps2_dev_command(dev, PS2_CMD_MOUSE_SET_RES, val, 1, NULL, 0) != B_OK + || ps2_dev_command(dev, PS2_CMD_MOUSE_SET_SCALE21, NULL, 0, NULL, 0) != B_OK - || ps2_dev_command(dev, PS2_MOUSE_CMD_SET_SCALE21, NULL, 0, NULL, 0) + || ps2_dev_command(dev, PS2_CMD_MOUSE_SET_SCALE21, NULL, 0, NULL, 0) != B_OK - || ps2_dev_command(dev, PS2_MOUSE_CMD_SET_SCALE21, NULL, 0, NULL, 0) + || ps2_dev_command(dev, PS2_CMD_MOUSE_SET_SCALE21, NULL, 0, NULL, 0) != B_OK) return B_ERROR; - if (ps2_dev_command(dev, PS2_MOUSE_CMD_GET_INFO, NULL, 0, val, 3) + if (ps2_dev_command(dev, PS2_CMD_MOUSE_GET_INFO, NULL, 0, val, 3) != B_OK) return B_ERROR; @@ -337,12 +328,12 @@ switch_hardware_tab(ps2_dev* dev, bool on) { uint8 val[3]; uint8 arg = 0x00; - uint8 command = PS2_MOUSE_CMD_SET_RES; + uint8 command = PS2_CMD_MOUSE_SET_RES; if (on) { arg = 0x0A; - command = PS2_MOUSE_CMD_SET_RATE; + command = PS2_CMD_KEYBOARD_SET_TYPEMATIC; } - if (ps2_dev_command(dev, PS2_MOUSE_CMD_GET_INFO, NULL, 0, val, 3) != B_OK + if (ps2_dev_command(dev, PS2_CMD_MOUSE_GET_INFO, NULL, 0, val, 3) != B_OK || ps2_dev_command(dev, PS2_CMD_DISABLE, NULL, 0, NULL, 0) != B_OK || ps2_dev_command(dev, PS2_CMD_DISABLE, NULL, 0, NULL, 0) != B_OK || ps2_dev_command(dev, command, &arg, 1, NULL, 0) != B_OK) @@ -355,9 +346,9 @@ switch_hardware_tab(ps2_dev* dev, bool on) status_t enable_passthrough(ps2_dev* dev, bool on) { - uint8 command = PS2_MOUSE_CMD_SET_SCALE11; + uint8 command = PS2_CMD_MOUSE_SET_SCALE11; if (on) - command = PS2_MOUSE_CMD_SET_SCALE21; + command = PS2_CMD_MOUSE_SET_SCALE21; if (ps2_dev_command(dev, command, NULL, 0, NULL, 0) != B_OK || ps2_dev_command(dev, command, NULL, 0, NULL, 0) != B_OK @@ -438,7 +429,7 @@ alps_open(const char *name, uint32 flags, void **_cookie) if ((sFoundModel->flags & ALPS_PASS) != 0 && enable_passthrough(dev, true) != B_OK) goto err4; - + // switch tap mode off if (switch_hardware_tab(dev, false) != B_OK) goto err4; @@ -455,7 +446,7 @@ alps_open(const char *name, uint32 flags, void **_cookie) && enable_passthrough(dev, false) != B_OK) goto err4; - if (ps2_dev_command(dev, PS2_MOUSE_CMD_SET_STREAM, NULL, 0, NULL, 0) != B_OK) + if (ps2_dev_command(dev, PS2_CMD_MOUSE_SET_STREAM, NULL, 0, NULL, 0) != B_OK) goto err4; if (ps2_dev_command(dev, PS2_CMD_ENABLE, NULL, 0, NULL, 0) != B_OK) @@ -633,4 +624,3 @@ device_hooks gALPSDeviceHooks = { alps_read, alps_write, }; - diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_alps.h b/src/add-ons/kernel/bus_managers/ps2/ps2_alps.h index e9dea0683d..4e25dc6485 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_alps.h +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_alps.h @@ -1,3 +1,10 @@ +/* + * Copyright 2011, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Clemens Zeidler (haiku@Clemens-Zeidler.de) + */ #ifndef ALPS_H #define ALPS_H diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_common.cpp b/src/add-ons/kernel/bus_managers/ps2/ps2_common.cpp index 37f902e74d..d0560f272b 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_common.cpp +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_common.cpp @@ -369,7 +369,7 @@ ps2_init(void) //ps2_selftest(); // Setup the command byte with disabled keyboard and AUX interrupts - // to prevent interrupts storm on some KBCs during active multiplexing + // to prevent interrupts storm on some KBCs during active multiplexing // activation procedure. Fixes #7635. status = ps2_setup_command_byte(false); if (status) { @@ -391,8 +391,9 @@ ps2_init(void) } if (gActiveMultiplexingEnabled) { - if (ps2_dev_command_timeout(&ps2_device[PS2_DEVICE_MOUSE], 0xe6, - NULL, 0, NULL, 0, 100000) == B_TIMED_OUT) { + if (ps2_dev_command_timeout(&ps2_device[PS2_DEVICE_MOUSE], + PS2_CMD_MOUSE_SET_SCALE11, NULL, 0, NULL, 0, 100000) + == B_TIMED_OUT) { INFO("ps2: accessing multiplexed mouse port 0 timed out, ignoring it!\n"); } else { ps2_service_notify_device_added(&ps2_device[PS2_DEVICE_MOUSE]); diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_common.h b/src/add-ons/kernel/bus_managers/ps2/ps2_common.h index fc302faead..c32c7349f0 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_common.h +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_common.h @@ -28,6 +28,7 @@ #else # define INFO(x...) #endif +#define ERROR(x...) dprintf(x) //#define TRACE_PS2 #ifdef TRACE_PS2 diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_defs.h b/src/add-ons/kernel/bus_managers/ps2/ps2_defs.h index b9f237cc1c..25fbf1af28 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_defs.h +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_defs.h @@ -48,7 +48,13 @@ #define PS2_BITS_TRANSLATE_SCANCODES 0x40 // data words +#define PS2_CMD_MOUSE_SET_SCALE11 0xe6 +#define PS2_CMD_MOUSE_SET_SCALE21 0xe7 +#define PS2_CMD_MOUSE_SET_RES 0xe8 +#define PS2_CMD_MOUSE_GET_INFO 0xe9 +#define PS2_CMD_MOUSE_SET_STREAM 0xea #define PS2_CMD_KEYBOARD_SET_LEDS 0xed +#define PS2_CMD_MOUSE_SET_POLL 0xf0 #define PS2_CMD_KEYBOARD_SET_TYPEMATIC 0xf3 #define PS2_CMD_ECHO 0xee #define PS2_CMD_TEST_PASSED 0xaa @@ -56,6 +62,7 @@ #define PS2_CMD_SET_SAMPLE_RATE 0xf3 #define PS2_CMD_ENABLE 0xf4 #define PS2_CMD_DISABLE 0xf5 +#define PS2_CMD_MOUSE_RESET_DIS 0xf6 #define PS2_CMD_RESET 0xff #define PS2_CMD_RESEND 0xfe @@ -79,6 +86,7 @@ #define PS2_PACKET_INTELLIMOUSE 4 #define PS2_PACKET_SYNAPTICS 6 #define PS2_PACKET_ALPS 6 +#define PS2_PACKET_ELANTECH 6 // version 1 is only 4 #define PS2_MAX_PACKET_SIZE 6 // Should be equal to the biggest packet size diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_dev.cpp b/src/add-ons/kernel/bus_managers/ps2/ps2_dev.cpp index 0cb799a5a4..4f7137b8e4 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_dev.cpp +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_dev.cpp @@ -14,6 +14,7 @@ #include "ps2_service.h" #include "ps2_alps.h" +#include "ps2_elantech.h" #include "ps2_standard_mouse.h" #include "ps2_synaptics.h" #include "ps2_trackpoint.h" @@ -88,6 +89,12 @@ ps2_dev_detect_pointing(ps2_dev *dev, device_hooks **hooks) goto dev_found; } + status = probe_elantech(dev); + if (status == B_OK) { + *hooks = &gElantechDeviceHooks; + goto dev_found; + } + // reset the mouse for the case that the previous probes leaf the mouse in // a undefined state status = ps2_reset_mouse(dev); @@ -190,7 +197,7 @@ ps2_dev_publish(ps2_dev *dev) if (atomic_get(&dev->flags) & PS2_FLAG_KEYB) { status = devfs_publish_device(dev->name, &gKeyboardDeviceHooks); } else { - // Check if this is the "pass-through" device and wait until + // Check if this is the "pass-through" device and wait until // the parent_dev goes to enabled state. It is required to prevent // from messing up the Synaptics command sequences in synaptics_open. if (dev->parent_dev) { @@ -204,7 +211,7 @@ ps2_dev_publish(ps2_dev *dev) snooze(timeout / 20); } TRACE("ps2: publishing %s: parent %s is %s; wait time %" B_PRId64 - "\n", dev->name, dev->parent_dev->name, + "\n", dev->name, dev->parent_dev->name, status == B_OK ? "enabled" : "busy", system_time() - start); } @@ -490,3 +497,23 @@ ps2_dev_command_timeout(ps2_dev *dev, uint8 cmd, const uint8 *out, return dev->command(dev, cmd, out, out_count, in, in_count, timeout); } + +status_t +ps2_dev_sliced_command(ps2_dev *dev, uint8 cmd) +{ + if (ps2_dev_command(dev, PS2_CMD_MOUSE_SET_SCALE11) != B_OK) + return B_ERROR; + uint8 val = (cmd >> 6) & 3; + if (ps2_dev_command(dev, PS2_CMD_MOUSE_SET_RES, &val, 1) != B_OK) + return B_ERROR; + val = (cmd >> 4) & 3; + if (ps2_dev_command(dev, PS2_CMD_MOUSE_SET_RES, &val, 1) != B_OK) + return B_ERROR; + val = (cmd >> 2) & 3; + if (ps2_dev_command(dev, PS2_CMD_MOUSE_SET_RES, &val, 1) != B_OK) + return B_ERROR; + val = cmd & 3; + if (ps2_dev_command(dev, PS2_CMD_MOUSE_SET_RES, &val, 1) != B_OK) + return B_ERROR; + return B_OK; +} diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_dev.h b/src/add-ons/kernel/bus_managers/ps2/ps2_dev.h index c8c283609f..229dbe0c0f 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_dev.h +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_dev.h @@ -76,10 +76,12 @@ void ps2_dev_exit(void); status_t standard_command_timeout(ps2_dev *dev, uint8 cmd, const uint8 *out, int out_count, uint8 *in, int in_count, bigtime_t timeout); -status_t ps2_dev_command(ps2_dev *dev, uint8 cmd, const uint8 *out, - int out_count, uint8 *in, int in_count); +status_t ps2_dev_command(ps2_dev *dev, uint8 cmd, const uint8 *out = NULL, + int out_count = 0, uint8 *in = NULL, int in_count = 0); status_t ps2_dev_command_timeout(ps2_dev *dev, uint8 cmd, const uint8 *out, int out_count, uint8 *in, int in_count, bigtime_t timeout); +status_t ps2_dev_sliced_command(ps2_dev *dev, uint8 cmd); + status_t ps2_reset_mouse(ps2_dev *dev); diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.cpp b/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.cpp new file mode 100644 index 0000000000..355bd4f03b --- /dev/null +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.cpp @@ -0,0 +1,801 @@ +/* + * Copyright 2013, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * Hardware specs taken from the linux driver, thanks a lot! + * Based on ps2_alps.c + * + * Authors: + * Jérôme Duval + */ + + +#include "ps2_elantech.h" + +#include +#include + +#include "ps2_service.h" + + +static int32 generate_event(timer* timer); + + +const bigtime_t kEventInterval = 1000 * 50; + + +class EventProducer { +public: + EventProducer() + { + fFired = false; + } + + status_t + FireEvent(elantech_cookie* cookie, uint8* package) + { + fCookie = cookie; + memcpy(fLastPackage, package, sizeof(uint8) * PS2_PACKET_ELANTECH); + + status_t status = add_timer(&fEventTimer, &generate_event, + kEventInterval, B_ONE_SHOT_RELATIVE_TIMER); + if (status == B_OK) + fFired = true; + return status; + } + + bool + CancelEvent() + { + if (!fFired) + return false; + fFired = false; + return cancel_timer(&fEventTimer); + } + + void + InjectEvent() + { + if (packet_buffer_write(fCookie->ring_buffer, fLastPackage, + PS2_PACKET_ELANTECH) != PS2_PACKET_ELANTECH) { + // buffer is full, drop new data + return; + } + release_sem_etc(fCookie->sem, 1, B_DO_NOT_RESCHEDULE); + } + +private: + bool fFired; + uint8 fLastPackage[PS2_PACKET_ELANTECH]; + timer fEventTimer; + elantech_cookie* fCookie; +}; + + +static EventProducer gEventProducer; + + +static int32 +generate_event(timer* timer) +{ + gEventProducer.InjectEvent(); + return 0; +} + + +const char* kElantechPath[4] = { + "input/touchpad/ps2/elantech_0", + "input/touchpad/ps2/elantech_1", + "input/touchpad/ps2/elantech_2", + "input/touchpad/ps2/elantech_3" +}; + + +#define ELANTECH_CMD_GET_ID 0x00 +#define ELANTECH_CMD_GET_VERSION 0x01 +#define ELANTECH_CMD_GET_CAPABILITIES 0x02 +#define ELANTECH_CMD_GET_SAMPLE 0x03 +#define ELANTECH_CMD_GET_RESOLUTION 0x04 + +#define ELANTECH_CMD_REGISTER_READ 0x10 +#define ELANTECH_CMD_REGISTER_WRITE 0x11 +#define ELANTECH_CMD_REGISTER_READWRITE 0x00 +#define ELANTECH_CMD_PS2_CUSTOM_CMD 0xf8 + + +// touchpad proportions +#define EDGE_MOTION_WIDTH 55 + +#define MIN_PRESSURE 0 +#define REAL_MAX_PRESSURE 50 +#define MAX_PRESSURE 255 + +#define ELANTECH_HISTORY_SIZE 256 + + +static hardware_specs gHardwareSpecs; + + +static status_t +get_elantech_movement(elantech_cookie *cookie, mouse_movement *movement) +{ + touch_event event; + uint8 event_buffer[PS2_PACKET_ELANTECH]; + + status_t status = acquire_sem_etc(cookie->sem, 1, B_CAN_INTERRUPT, 0); + if (status < B_OK) + return status; + + if (!cookie->dev->active) { + TRACE("ELANTECH: read_event: Error device no longer active\n"); + return B_ERROR; + } + + if (packet_buffer_read(cookie->ring_buffer, event_buffer, + cookie->dev->packet_size) != cookie->dev->packet_size) { + TRACE("ELANTECH: error copying buffer\n"); + return B_ERROR; + } + + if (cookie->crcEnabled && (event_buffer[3] & 0x08) != 0) { + TRACE("ELANTECH: bad crc buffer\n"); + return B_ERROR; + } else if (!cookie->crcEnabled && ((event_buffer[0] & 0x0c) != 0x04 + || (event_buffer[3] & 0x1c) != 0x10)) { + TRACE("ELANTECH: bad crc buffer\n"); + return B_ERROR; + } + uint8 type = event_buffer[3] & 3; + TRACE("ELANTECH: packet type %d\n", type); + TRACE("ELANTECH: packet content 0x%02x%02x%02x%02x%02x%02x\n", + event_buffer[0], event_buffer[1], event_buffer[2], event_buffer[3], + event_buffer[4], event_buffer[5]); + switch (type) { + case 0: + // fingers + cookie->fingers = event_buffer[1] & 0x1f; + break; + case 1: + if ((((event_buffer[3] & 0xe0) >> 5) - 1) != 0) { + // only process first finger + return B_OK; + } + event.zPressure = (event_buffer[1] & 0xf0) + | ((event_buffer[4] & 0xf0) >> 4); + + cookie->previousZ = event.zPressure; + + event.xPosition = ((event_buffer[1] & 0xf) << 8) | event_buffer[2]; + event.yPosition = (((event_buffer[4] & 0xf) << 8) + | event_buffer[5]); + TRACE("ELANTECH: buttons 0x%x x %ld y %ld z %d\n", + event.buttons, event.xPosition, event.yPosition, + event.zPressure); + break; + case 2: + TRACE("ELANTECH: packet type motion\n"); + // TODO + return B_OK; + default: + TRACE("ELANTECH: unknown packet type %d\n", type); + return B_ERROR; + } + + event.buttons = 0; + // finger on touchpad + if ((cookie->fingers & 1) != 0) { + // finger with normal width + event.wValue = 4; + } else { + event.wValue = 3; + } + status = cookie->movementMaker.EventToMovement(&event, movement); + + if (cookie->movementMaker.WasEdgeMotion() + || cookie->movementMaker.TapDragStarted()) { + gEventProducer.FireEvent(cookie, event_buffer); + } + + return status; +} + + +static void +default_settings(touchpad_settings *set) +{ + memcpy(set, &kDefaultTouchpadSettings, sizeof(touchpad_settings)); +} + + +static status_t +synaptics_dev_send_command(ps2_dev* dev, uint8 cmd, uint8 *in, int in_count) +{ + uint8 val; + if (ps2_dev_sliced_command(dev, cmd) != B_OK + || ps2_dev_command(dev, PS2_CMD_MOUSE_GET_INFO, NULL, 0, in, in_count) + != B_OK) { + TRACE("ELANTECH: synaptics_dev_send_command failed\n"); + return B_ERROR; + } + return B_OK; +} + + +static status_t +elantech_dev_send_command(ps2_dev* dev, uint8 cmd, uint8 *in, int in_count) +{ + uint8 val; + if (ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, cmd) != B_OK + || ps2_dev_command(dev, PS2_CMD_MOUSE_GET_INFO, NULL, 0, in, in_count) + != B_OK) { + TRACE("ELANTECH: elantech_dev_send_command failed\n"); + return B_ERROR; + } + return B_OK; +} + + +status_t +probe_elantech(ps2_dev* dev) +{ + int i; + uint8 val[3]; + TRACE("ELANTECH: probe\n"); + + ps2_dev_command(dev, PS2_CMD_MOUSE_RESET_DIS); + + if (ps2_dev_command(dev, PS2_CMD_DISABLE) != B_OK + || ps2_dev_command(dev, PS2_CMD_MOUSE_SET_SCALE11) != B_OK + || ps2_dev_command(dev, PS2_CMD_MOUSE_SET_SCALE11) != B_OK + || ps2_dev_command(dev, PS2_CMD_MOUSE_SET_SCALE11) != B_OK) { + TRACE("ELANTECH: not found (1)\n"); + return B_ERROR; + } + + if (ps2_dev_command(dev, PS2_CMD_MOUSE_GET_INFO, NULL, 0, val, 3) + != B_OK) { + TRACE("ELANTECH: not found (2)\n"); + return B_ERROR; + } + + if (val[0] != 0x3c || val[1] != 0x3 || (val[2] != 0xc8 && val[2] != 0x0)) { + TRACE("ELANTECH: not found (3)\n"); + return B_ERROR; + } + + val[0] = 0; + if (synaptics_dev_send_command(dev, ELANTECH_CMD_GET_VERSION, val, 3) + != B_OK) { + TRACE("ELANTECH: not found (4)\n"); + return B_ERROR; + } + + if (val[0] == 0x0 || val[2] == 10 || val[2] == 20 || val[2] == 40 + || val[2] == 60 || val[2] == 80 || val[2] == 100 || val[2] == 200) { + TRACE("ELANTECH: not found (5)\n"); + return B_ERROR; + } + + INFO("Elantech found\n"); + + dev->name = kElantechPath[dev->idx]; + dev->packet_size = PS2_PACKET_ELANTECH; + + return B_OK; +} + + +static status_t +elantech_write_reg(elantech_cookie* cookie, uint8 reg, uint8 value) +{ + if (reg < 0x7 || reg > 0x26) + return B_BAD_VALUE; + if (reg > 0x11 && reg < 0x20) + return B_BAD_VALUE; + + ps2_dev* dev = cookie->dev; + switch (cookie->version) { + case 1: + // TODO + return B_ERROR; + break; + case 2: + if (ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_REGISTER_WRITE) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, reg) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, value) != B_OK + || ps2_dev_command(dev, PS2_CMD_MOUSE_SET_SCALE11) != B_OK) + return B_ERROR; + break; + case 3: + if (ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_REGISTER_READWRITE) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, reg) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, value) != B_OK + || ps2_dev_command(dev, PS2_CMD_MOUSE_SET_SCALE11) != B_OK) + return B_ERROR; + break; + case 4: + if (ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_REGISTER_READWRITE) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, reg) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_REGISTER_READWRITE) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, value) != B_OK + || ps2_dev_command(dev, PS2_CMD_MOUSE_SET_SCALE11) != B_OK) + return B_ERROR; + break; + default: + TRACE("ELANTECH: read_write_reg: unknown version\n"); + return B_ERROR; + } + return B_OK; +} + + +static status_t +elantech_read_reg(elantech_cookie* cookie, uint8 reg, uint8 *value) +{ + if (reg < 0x7 || reg > 0x26) + return B_BAD_VALUE; + if (reg > 0x11 && reg < 0x20) + return B_BAD_VALUE; + + ps2_dev* dev = cookie->dev; + uint8 val[3]; + switch (cookie->version) { + case 1: + // TODO + return B_ERROR; + break; + case 2: + if (ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_REGISTER_READ) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, reg) != B_OK + || ps2_dev_command(dev, PS2_CMD_MOUSE_GET_INFO, NULL, 0, val, + 3) != B_OK) + return B_ERROR; + break; + case 3: + case 4: + if (ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_REGISTER_READWRITE) + != B_OK + || ps2_dev_command(dev, ELANTECH_CMD_PS2_CUSTOM_CMD) != B_OK + || ps2_dev_command(dev, reg) != B_OK + || ps2_dev_command(dev, PS2_CMD_MOUSE_GET_INFO, NULL, 0, val, + 3) != B_OK) + return B_ERROR; + break; + default: + TRACE("ELANTECH: read_write_reg: unknown version\n"); + return B_ERROR; + } + if (cookie->version == 4) + *value = val[1]; + else + *value = val[0]; + + return B_OK; +} + + + +static status_t +switch_hardware_tab(ps2_dev* dev, bool on) +{ + uint8 val[3]; + uint8 arg = 0x00; + uint8 command = PS2_CMD_MOUSE_SET_RES; + if (on) { + arg = 0x0A; + command = PS2_CMD_SET_SAMPLE_RATE; + } + if (ps2_dev_command(dev, PS2_CMD_MOUSE_GET_INFO, NULL, 0, val, 3) != B_OK + || ps2_dev_command(dev, PS2_CMD_DISABLE, NULL, 0, NULL, 0) != B_OK + || ps2_dev_command(dev, PS2_CMD_DISABLE, NULL, 0, NULL, 0) != B_OK + || ps2_dev_command(dev, command, &arg, 1, NULL, 0) != B_OK) + return B_ERROR; + + return B_OK; +} + + +static status_t +get_resolution_v4(elantech_cookie* cookie, uint32* x, uint32* y) +{ + uint8 val[3]; + if (elantech_dev_send_command(cookie->dev, ELANTECH_CMD_GET_RESOLUTION, + val, 3) != B_OK) + return B_ERROR; + *x = (val[1] & 0xf) * 10 + 790; + *y = ((val[1] & 0xf) >> 4) * 10 + 790; + return B_OK; +} + + +static status_t +get_range(elantech_cookie* cookie, uint32* x_min, uint32* y_min, uint32* x_max, + uint32* y_max, uint32 *width) +{ + status_t status = B_OK; + uint8 val[3]; + switch (cookie->version) { + case 1: + *x_min = 32; + *y_min = 32; + *x_max = 544; + *y_max = 344; + *width = 0; + break; + case 2: + // TODO + break; + case 3: + if ((cookie->send_command)(cookie->dev, ELANTECH_CMD_GET_ID, val, 3) + != B_OK) { + return B_ERROR; + } + *x_min = 0; + *y_min = 0; + *x_max = ((val[0] & 0xf) << 8) | val[1]; + *y_max = ((val[0] & 0xf0) << 4) | val[2]; + *width = 0; + break; + case 4: + if ((cookie->send_command)(cookie->dev, ELANTECH_CMD_GET_ID, val, 3) + != B_OK) { + return B_ERROR; + } + *x_min = 0; + *y_min = 0; + *x_max = ((val[0] & 0xf) << 8) | val[1]; + *y_max = ((val[0] & 0xf0) << 4) | val[2]; + if (cookie->capabilities[1] < 2 || cookie->capabilities[1] > *x_max) + return B_ERROR; + *width = *x_max / (cookie->capabilities[1] - 1); + break; + } + return B_OK; +} + + +static status_t +enable_absolute_mode(elantech_cookie* cookie) +{ + status_t status = B_OK; + switch (cookie->version) { + case 1: + status = elantech_write_reg(cookie, 0x10, 0x16); + if (status == B_OK) + status = elantech_write_reg(cookie, 0x11, 0x8f); + break; + case 2: + status = elantech_write_reg(cookie, 0x10, 0x54); + if (status == B_OK) + status = elantech_write_reg(cookie, 0x11, 0x88); + if (status == B_OK) + status = elantech_write_reg(cookie, 0x12, 0x60); + break; + case 3: + status = elantech_write_reg(cookie, 0x10, 0xb); + break; + case 4: + status = elantech_write_reg(cookie, 0x7, 0x1); + break; + + } + + if (cookie->version < 4) { + uint8 val; + + for (uint8 retry = 0; retry < 5; retry++) { + status = elantech_read_reg(cookie, 0x10, &val); + if (status != B_OK) + break; + snooze(100); + } + } + + return status; +} + + +status_t +elantech_open(const char *name, uint32 flags, void **_cookie) +{ + TRACE("ELANTECH: open %s\n", name); + ps2_dev* dev; + int i; + for (dev = NULL, i = 0; i < PS2_DEVICE_COUNT; i++) { + if (0 == strcmp(ps2_device[i].name, name)) { + dev = &ps2_device[i]; + break; + } + } + + if (dev == NULL) { + TRACE("ps2: dev = NULL\n"); + return B_ERROR; + } + + if (atomic_or(&dev->flags, PS2_FLAG_OPEN) & PS2_FLAG_OPEN) + return B_BUSY; + + elantech_cookie* cookie = (elantech_cookie*)malloc( + sizeof(elantech_cookie)); + if (cookie == NULL) + goto err1; + memset(cookie, 0, sizeof(*cookie)); + + cookie->movementMaker.Init(); + cookie->previousZ = 0; + *_cookie = cookie; + + cookie->dev = dev; + dev->cookie = cookie; + dev->disconnect = &elantech_disconnect; + dev->handle_int = &elantech_handle_int; + + default_settings(&cookie->settings); + + dev->packet_size = PS2_PACKET_ELANTECH; + + cookie->ring_buffer = create_packet_buffer( + ELANTECH_HISTORY_SIZE * dev->packet_size); + if (cookie->ring_buffer == NULL) { + TRACE("ELANTECH: can't allocate mouse actions buffer\n"); + goto err2; + } + // create the mouse semaphore, used for synchronization between + // the interrupt handler and the read operation + cookie->sem = create_sem(0, "ps2_elantech_sem"); + if (cookie->sem < 0) { + TRACE("ELANTECH: failed creating semaphore!\n"); + goto err3; + } + + uint8 val[3]; + if (synaptics_dev_send_command(dev, ELANTECH_CMD_GET_VERSION, val, 3) + != B_OK) { + TRACE("ELANTECH: get version failed!\n"); + goto err4; + } + cookie->fwVersion = (val[0] << 16) | (val[1] << 8) | val[2]; + if (cookie->fwVersion < 0x020030 || cookie->fwVersion == 0x020600) + cookie->version = 1; + else { + switch (val[0] & 0xf) { + case 2: + case 4: + cookie->version = 2; + break; + case 5: + cookie->version = 3; + case 6: + case 7: + cookie->version = 4; + break; + default: + TRACE("ELANTECH: unknown version!\n"); + goto err4; + } + } + TRACE("ELANTECH: version 0x%lx (0x%lx)\n", cookie->version, + cookie->fwVersion); + + if (cookie->version >= 3) + cookie->send_command = &elantech_dev_send_command; + else + cookie->send_command = &synaptics_dev_send_command; + cookie->crcEnabled = (cookie->fwVersion & 0x4000) == 0x4000; + + if ((cookie->send_command)(cookie->dev, ELANTECH_CMD_GET_CAPABILITIES, + cookie->capabilities, 3) != B_OK) { + TRACE("ELANTECH: get capabilities failed!\n"); + return B_ERROR; + } + + if (enable_absolute_mode(cookie) != B_OK) { + TRACE("ELANTECH: failed enabling absolute mode!\n"); + goto err4; + } + TRACE("ELANTECH: enabled absolute mode!\n"); + + uint32 x_min, x_max, y_min, y_max, width; + if (get_range(cookie, &x_min, &y_min, &x_max, &y_max, &width) != B_OK) { + TRACE("ELANTECH: get range failed!\n"); + goto err4; + } + + TRACE("ELANTECH: range x %ld-%ld y %ld-%ld (%ld)\n", x_min, x_max, + y_min, y_max, width); + + uint32 x_res, y_res; + if (get_resolution_v4(cookie, &x_res, &y_res) != B_OK) { + TRACE("ELANTECH: get resolution failed!\n"); + goto err4; + } + + TRACE("ELANTECH: resolution x %ld y %ld (dpi)\n", x_res, y_res); + + gHardwareSpecs.edgeMotionWidth = EDGE_MOTION_WIDTH; + + gHardwareSpecs.areaStartX = x_min; + gHardwareSpecs.areaEndX = x_max; + gHardwareSpecs.areaStartY = y_min; + gHardwareSpecs.areaEndY = y_max; + + gHardwareSpecs.minPressure = MIN_PRESSURE; + gHardwareSpecs.realMaxPressure = REAL_MAX_PRESSURE; + gHardwareSpecs.maxPressure = MAX_PRESSURE; + + cookie->movementMaker.SetSettings(&cookie->settings); + cookie->movementMaker.SetSpecs(&gHardwareSpecs); + + if (ps2_dev_command(dev, PS2_CMD_ENABLE, NULL, 0, NULL, 0) != B_OK) + goto err4; + + atomic_or(&dev->flags, PS2_FLAG_ENABLED); + + TRACE("ELANTECH: open %s success\n", name); + return B_OK; + +err4: + delete_sem(cookie->sem); +err3: + delete_packet_buffer(cookie->ring_buffer); +err2: + free(cookie); +err1: + atomic_and(&dev->flags, ~PS2_FLAG_OPEN); + + TRACE("ELANTECH: open %s failed\n", name); + return B_ERROR; +} + + +status_t +elantech_close(void *_cookie) +{ + gEventProducer.CancelEvent(); + + elantech_cookie *cookie = (elantech_cookie*)_cookie; + + ps2_dev_command_timeout(cookie->dev, PS2_CMD_DISABLE, NULL, 0, NULL, 0, + 150000); + + delete_packet_buffer(cookie->ring_buffer); + delete_sem(cookie->sem); + + atomic_and(&cookie->dev->flags, ~PS2_FLAG_OPEN); + atomic_and(&cookie->dev->flags, ~PS2_FLAG_ENABLED); + + // Reset the touchpad so it generate standard ps2 packets instead of + // extended ones. If not, BeOS is confused with such packets when rebooting + // without a complete shutdown. + status_t status = ps2_reset_mouse(cookie->dev); + if (status != B_OK) { + INFO("ps2: reset failed\n"); + return B_ERROR; + } + + TRACE("ELANTECH: close %s done\n", cookie->dev->name); + return B_OK; +} + + +status_t +elantech_freecookie(void *_cookie) +{ + free(_cookie); + return B_OK; +} + + +status_t +elantech_ioctl(void *_cookie, uint32 op, void *buffer, size_t length) +{ + elantech_cookie *cookie = (elantech_cookie*)_cookie; + mouse_movement movement; + status_t status; + + switch (op) { + case MS_READ: + TRACE("ELANTECH: MS_READ get event\n"); + if ((status = get_elantech_movement(cookie, &movement)) != B_OK) + return status; + return user_memcpy(buffer, &movement, sizeof(movement)); + + case MS_IS_TOUCHPAD: + TRACE("ELANTECH: MS_IS_TOUCHPAD\n"); + return B_OK; + + case MS_SET_TOUCHPAD_SETTINGS: + TRACE("ELANTECH: MS_SET_TOUCHPAD_SETTINGS"); + user_memcpy(&cookie->settings, buffer, sizeof(touchpad_settings)); + return B_OK; + + case MS_SET_CLICKSPEED: + TRACE("ELANTECH: ioctl MS_SETCLICK (set click speed)\n"); + return user_memcpy(&cookie->movementMaker.click_speed, buffer, + sizeof(bigtime_t)); + + default: + TRACE("ELANTECH: unknown opcode: %ld\n", op); + return B_BAD_VALUE; + } +} + + +static status_t +elantech_read(void* cookie, off_t pos, void* buffer, size_t* _length) +{ + *_length = 0; + return B_NOT_ALLOWED; +} + + +static status_t +elantech_write(void* cookie, off_t pos, const void* buffer, size_t* _length) +{ + *_length = 0; + return B_NOT_ALLOWED; +} + + +int32 +elantech_handle_int(ps2_dev* dev) +{ + elantech_cookie* cookie = (elantech_cookie*)dev->cookie; + + // we got a real event cancel the fake event + gEventProducer.CancelEvent(); + + uint8 val; + val = cookie->dev->history[0].data; + cookie->buffer[cookie->packet_index] = val; + cookie->packet_index++; + + if (cookie->packet_index < PS2_PACKET_ELANTECH) + return B_HANDLED_INTERRUPT; + + cookie->packet_index = 0; + if (packet_buffer_write(cookie->ring_buffer, + cookie->buffer, cookie->dev->packet_size) + != cookie->dev->packet_size) { + // buffer is full, drop new data + return B_HANDLED_INTERRUPT; + } + release_sem_etc(cookie->sem, 1, B_DO_NOT_RESCHEDULE); + return B_INVOKE_SCHEDULER; +} + + +void +elantech_disconnect(ps2_dev *dev) +{ + elantech_cookie *cookie = (elantech_cookie*)dev->cookie; + // the mouse device might not be opened at this point + INFO("ELANTECH: elantech_disconnect %s\n", dev->name); + if ((dev->flags & PS2_FLAG_OPEN) != 0) + release_sem(cookie->sem); +} + + +device_hooks gElantechDeviceHooks = { + elantech_open, + elantech_close, + elantech_freecookie, + elantech_ioctl, + elantech_read, + elantech_write, +}; diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.h b/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.h new file mode 100644 index 0000000000..b68a7bb369 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_elantech.h @@ -0,0 +1,59 @@ +/* + * Copyright 2013, Haiku, Inc. + * Distributed under the terms of the MIT License. + * + * The elantech_model_info struct and all the hardware specs are taken from the + * linux driver, thanks a lot! + * + * Authors: + * Jérôme Duval + */ +#ifndef _PS2_ELANTECH_H +#define _PS2_ELANTECH_H + + +#include + +#include + +#include "movement_maker.h" +#include "packet_buffer.h" +#include "ps2_dev.h" + + +typedef struct { + ps2_dev* dev; + + sem_id sem; + struct packet_buffer* ring_buffer; + size_t packet_index; + uint8 buffer[PS2_PACKET_ELANTECH]; + uint8 mode; + + uint8 previousZ; + TouchpadMovement movementMaker; + + touchpad_settings settings; + uint32 version; + uint32 fwVersion; + uint8 capabilities[3]; + bool crcEnabled; + uint32 fingers; + status_t (*send_command)(ps2_dev* dev, uint8 cmd, uint8 *in, int in_count); +} elantech_cookie; + + +status_t probe_elantech(ps2_dev *dev); + +status_t elantech_open(const char *name, uint32 flags, void **_cookie); +status_t elantech_close(void *_cookie); +status_t elantech_freecookie(void *_cookie); +status_t elantech_ioctl(void *_cookie, uint32 op, void *buffer, size_t length); + +int32 elantech_handle_int(ps2_dev *dev); +void elantech_disconnect(ps2_dev *dev); + +extern device_hooks gElantechDeviceHooks; + + +#endif /* _PS2_ELANTECH_H */ From 1f4aeff06acc16f95e407e3a2265dbb91e7e6d32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 23 Sep 2013 20:08:27 +0200 Subject: [PATCH 131/137] Some places where to find OpenFirmware specs... --- docs/develop/ports/ppc/mac/urls.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/develop/ports/ppc/mac/urls.txt b/docs/develop/ports/ppc/mac/urls.txt index b0cf634ba3..7e48f652d4 100644 --- a/docs/develop/ports/ppc/mac/urls.txt +++ b/docs/develop/ports/ppc/mac/urls.txt @@ -7,3 +7,5 @@ http://www.netneurotic.net/mac/openfirmware.html http://www.netbsd.org/ports/macppc/faq.html http://mail-index.netbsd.org/port-macppc/1999/03/21/0001.html http://mail-index.netbsd.org/port-macppc/1999/06/25/0006.html +http://ps-2.kev009.com/solinno.co.uk/7043-140/files/docs/ {OF,PReP} +http://www.openfirmware.org/1275/bindings/chrp/ From 2b66a08acb5ff1e603fc47b0c54fb5cfe8f1066c Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Wed, 25 Sep 2013 00:58:43 +0200 Subject: [PATCH 132/137] nfs4: Ignore superfluous slashes and get proper NFS4 share name --- .../kernel/file_systems/nfs4/FileSystem.cpp | 34 +++++++++---------- .../kernel/file_systems/nfs4/FileSystem.h | 3 +- .../file_systems/nfs4/kernel_interface.cpp | 21 ++++++++---- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp index 184e79a373..51c1600c25 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp @@ -125,8 +125,8 @@ GetInodeNames(const char** root, const char* _path) status_t -FileSystem::Mount(FileSystem** _fs, RPC::Server* serv, const char* fsPath, - dev_t id, const MountConfiguration& configuration) +FileSystem::Mount(FileSystem** _fs, RPC::Server* serv, const char* serverName, + const char* fsPath, dev_t id, const MountConfiguration& configuration) { ASSERT(_fs != NULL); ASSERT(serv != NULL); @@ -222,23 +222,23 @@ FileSystem::Mount(FileSystem** _fs, RPC::Server* serv, const char* fsPath, result = Inode::CreateInode(fs, fi, &inode); if (result != B_OK) return result; + RootInode* rootInode = reinterpret_cast(inode); + fs->fRoot = rootInode; - char* name = strrchr(fsPath, '/'); - if (name != NULL) { - name++; - reinterpret_cast(inode)->SetName(name); - } else if (fsPath[0] != '\0') - reinterpret_cast(inode)->SetName(fsPath); - else { - char* address = serv->ID().UniversalAddress(); - if (address != NULL) - reinterpret_cast(inode)->SetName(address); - else - reinterpret_cast(inode)->SetName("NFS4 Share"); - free(address); - } + char* fsName = strdup(fsPath); + if (fsName == NULL) + return B_NO_MEMORY; + for (int i = strlen(fsName) - 1; i >= 0 && fsName[i] == '/'; i--) + fsName[i] = '\0'; - fs->fRoot = reinterpret_cast(inode); + char* name = strrchr(fsName, '/'); + if (name != NULL) + rootInode->SetName(name + 1); + else if (fsName[0] != '\0') + rootInode->SetName(fsName); + else + rootInode->SetName(serverName); + free(fsName); fs->NFSServer()->AddFileSystem(fs); *_fs = fs; diff --git a/src/add-ons/kernel/file_systems/nfs4/FileSystem.h b/src/add-ons/kernel/file_systems/nfs4/FileSystem.h index 5d16d8d477..5ca172d484 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileSystem.h +++ b/src/add-ons/kernel/file_systems/nfs4/FileSystem.h @@ -32,7 +32,8 @@ struct MountConfiguration { class FileSystem : public DoublyLinkedListLinkImpl { public: static status_t Mount(FileSystem** pfs, RPC::Server* serv, - const char* path, dev_t id, + const char* path, const char* serverName, + dev_t id, const MountConfiguration& configuration); ~FileSystem(); diff --git a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp index b8f7294dff..2f26e42a62 100644 --- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp @@ -74,8 +74,8 @@ CreateNFS4Server(RPC::Server* serv) // dirtime=X - attempt revalidate directory cache not more often than each X // seconds static status_t -ParseArguments(const char* _args, AddressResolver** address, char** _path, - MountConfiguration* conf) +ParseArguments(const char* _args, AddressResolver** address, char** _server, + char** _path, MountConfiguration* conf) { if (_args == NULL) return B_BAD_VALUE; @@ -94,12 +94,18 @@ ParseArguments(const char* _args, AddressResolver** address, char** _path, return B_MISMATCHED_VALUES; *path++ = '\0'; - *address = new AddressResolver(args); - if (*address == NULL) + *_server = strdup(args); + if (*_server == NULL) return B_NO_MEMORY; + *address = new AddressResolver(args); + if (*address == NULL) { + delete *_server; + return B_NO_MEMORY; + } *_path = strdup(path); if (*_path == NULL) { + delete *_server; delete *address; return B_NO_MEMORY; } @@ -176,7 +182,8 @@ nfs4_mount(fs_volume* volume, const char* device, uint32 flags, AddressResolver* resolver; MountConfiguration config; char* path; - result = ParseArguments(args, &resolver, &path, &config); + char* serverName; + result = ParseArguments(args, &resolver, &serverName, &path, &config); if (result != B_OK) return result; MemoryDeleter pathDeleter(path); @@ -188,7 +195,9 @@ nfs4_mount(fs_volume* volume, const char* device, uint32 flags, return result; FileSystem* fs; - result = FileSystem::Mount(&fs, server, path, volume->id, config); + result = FileSystem::Mount(&fs, server, serverName, path, volume->id, + config); + free(serverName); if (result != B_OK) { gRPCServerManager->Release(server); return result; From e813a158461d96a8219c0fc7166ce87d4d0d9ebc Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Wed, 25 Sep 2013 18:39:00 +0200 Subject: [PATCH 133/137] Minimal support for uname -p * This is used by cmake to know which CPU to build for. --- src/bin/coreutils/src/uname.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/bin/coreutils/src/uname.c b/src/bin/coreutils/src/uname.c index f85d7e9124..16b0b33c94 100644 --- a/src/bin/coreutils/src/uname.c +++ b/src/bin/coreutils/src/uname.c @@ -50,6 +50,10 @@ # include #endif +#ifdef __HAIKU__ +# include +#endif + #include "system.h" #include "error.h" #include "quote.h" @@ -339,6 +343,23 @@ main (int argc, char **argv) # endif } #endif + +#ifdef __HAIKU__ + { + system_info sysinfo; + get_system_info(&sysinfo); + + switch (sysinfo.platform_type) { + case B_AT_CLONE_PLATFORM: + element = "x86"; + break; + case B_64_BIT_PC_PLATFORM: + element = "x86_64"; + break; + } + } +#endif + if (! (toprint == UINT_MAX && element == unknown)) print_element (element); } From e1d4323c6c565fd36af08f5f2ee8ed8e2160bdf8 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Wed, 25 Sep 2013 20:45:44 -0500 Subject: [PATCH 134/137] radeon_hd: Style cleanup of display.cpp * These errors slipped in from an external patch * No functional change --- src/add-ons/accelerants/radeon_hd/display.cpp | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/add-ons/accelerants/radeon_hd/display.cpp b/src/add-ons/accelerants/radeon_hd/display.cpp index 3a2238c005..172ac8d156 100644 --- a/src/add-ons/accelerants/radeon_hd/display.cpp +++ b/src/add-ons/accelerants/radeon_hd/display.cpp @@ -611,8 +611,8 @@ display_dce45_crtc_load_lut(uint8 crtcID) if (info.dceMajor >= 5) { Write32(OUT, NI_INPUT_CSC_CONTROL + regs->crtcOffset, - (NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) | - NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS))); + (NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) + | NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS))); Write32(OUT, NI_PRESCALE_GRPH_CONTROL + regs->crtcOffset, NI_GRPH_PRESCALE_BYPASS); Write32(OUT, NI_PRESCALE_OVL_CONTROL + regs->crtcOffset, @@ -638,17 +638,15 @@ display_dce45_crtc_load_lut(uint8 crtcID) Write32(OUT, EVERGREEN_DC_LUT_RW_INDEX, 0); for (int i = 0; i < 256; i++) { Write32(OUT, EVERGREEN_DC_LUT_30_COLOR + regs->crtcOffset, - (r[i] << 20) | - (g[i] << 10) | - (b[i] << 0)); + (r[i] << 20) | (g[i] << 10) | (b[i] << 0)); } if (info.dceMajor >= 5) { Write32(OUT, NI_DEGAMMA_CONTROL + regs->crtcOffset, - (NI_GRPH_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | - NI_OVL_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | - NI_ICON_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | - NI_CURSOR_DEGAMMA_MODE(NI_DEGAMMA_BYPASS))); + (NI_GRPH_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) + | NI_OVL_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) + | NI_ICON_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) + | NI_CURSOR_DEGAMMA_MODE(NI_DEGAMMA_BYPASS))); Write32(OUT, NI_GAMUT_REMAP_CONTROL + regs->crtcOffset, (NI_GRPH_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS) | NI_OVL_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS))); @@ -693,9 +691,7 @@ display_avivo_crtc_load_lut(uint8 crtcID) Write32(OUT, AVIVO_DC_LUT_RW_INDEX, 0); for (int i = 0; i < 256; i++) { Write32(OUT, AVIVO_DC_LUT_30_COLOR, - (r[i] << 20) | - (g[i] << 10) | - (b[i] << 0)); + (r[i] << 20) | (g[i] << 10) | (b[i] << 0)); } Write32(OUT, AVIVO_D1GRPH_LUT_SEL + regs->crtcOffset, crtcID); From 53e2862144033d76896d597e315ac33ff030f9a4 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Wed, 25 Sep 2013 20:49:15 -0500 Subject: [PATCH 135/137] radeon_hd: Style cleanup of displayport.cpp * These errors slipped in from an external patch * No functional change --- src/add-ons/accelerants/radeon_hd/displayport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/add-ons/accelerants/radeon_hd/displayport.cpp b/src/add-ons/accelerants/radeon_hd/displayport.cpp index a2421a54b9..c777285611 100644 --- a/src/add-ons/accelerants/radeon_hd/displayport.cpp +++ b/src/add-ons/accelerants/radeon_hd/displayport.cpp @@ -772,7 +772,7 @@ dp_link_train(uint8 crtcID) { TRACE("%s\n", __func__); - uint32 connectorIndex = gDisplay[crtcID]->connectorIndex; + uint32 connectorIndex = gDisplay[crtcID]->connectorIndex; dp_info* dp = &gConnector[connectorIndex]->dpInfo; display_mode* mode = &gDisplay[crtcID]->currentMode; From 1bc85a38d543589e6094ed27cf410f69540b35c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Thu, 26 Sep 2013 21:19:11 +0200 Subject: [PATCH 136/137] libroot: spawn_thread() now creates a detached pthread. * __pthread_destroy_thread() will in turn free the pthread_thread object. * this fixes a leak of 2072 bytes on each thread construction/destruction and #9945. MediaExtractor spawns a thread on construction, which leaked its pthread_thread object on destuction. --- src/system/libroot/os/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/libroot/os/thread.c b/src/system/libroot/os/thread.c index 41721453d3..0f14f29d9d 100644 --- a/src/system/libroot/os/thread.c +++ b/src/system/libroot/os/thread.c @@ -110,6 +110,7 @@ spawn_thread(thread_func entry, const char *name, int32 priority, void *data) __pthread_init_creation_attributes(NULL, thread, &thread_entry, entry, thread, name, &attributes); + thread->flags |= THREAD_DETACHED; attributes.priority = priority; @@ -256,4 +257,3 @@ snooze_until(bigtime_t timeout, int timeBase) { return _kern_snooze_etc(timeout, timeBase, B_ABSOLUTE_TIMEOUT, NULL); } - From 6c7caf44dfbb7d6ff766089e4006a50454220750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 27 Sep 2013 00:21:04 +0200 Subject: [PATCH 137/137] NetworkStatus now joins networks by address instead of name. * This solves part of ticket #10008. --- src/apps/networkstatus/NetworkStatusView.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/apps/networkstatus/NetworkStatusView.cpp b/src/apps/networkstatus/NetworkStatusView.cpp index cdff48eb65..45b5a4af45 100644 --- a/src/apps/networkstatus/NetworkStatusView.cpp +++ b/src/apps/networkstatus/NetworkStatusView.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006-2012, Haiku, Inc. All rights reserved. + * Copyright 2006-2013, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -288,10 +288,12 @@ NetworkStatusView::MessageReceived(BMessage* message) { const char* deviceName; const char* name; + BNetworkAddress address; if (message->FindString("device", &deviceName) == B_OK - && message->FindString("name", &name) == B_OK) { + && message->FindString("name", &name) == B_OK + && message->FindFlat("address", &address) == B_OK) { BNetworkDevice device(deviceName); - status_t status = device.JoinNetwork(name); + status_t status = device.JoinNetwork(address); if (status != B_OK) { BString text = B_TRANSLATE("Could not join wireless network:\n"); @@ -467,6 +469,7 @@ NetworkStatusView::MouseDown(BPoint point) BMessage* message = new BMessage(kMsgJoinNetwork); message->AddString("device", wifiInterface); message->AddString("name", network.name); + message->AddFlat("address", &network.address); BMenuItem* item = new WirelessNetworkMenuItem(network.name, network.signal_strength, @@ -506,7 +509,7 @@ NetworkStatusView::_AboutRequested() { BAboutWindow* window = new BAboutWindow( B_TRANSLATE_SYSTEM_NAME("NetworkStatus"), kSignature); - + const char* authors[] = { "Axel Dörfler", "Hugo Santos",