aboutsummaryrefslogtreecommitdiff
path: root/common/string.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2023-05-29 21:31:09 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2023-05-29 21:31:09 +0300
commit3ace1ddd76b9c04f3ed23883de6279b4485612e8 (patch)
tree2f4af69d70967c2455cb83d8c18a5416c8d1b54d /common/string.c
parentb7f53b9a9001708dea5303faf52f1b508eefb712 (diff)
downloadkmi-3ace1ddd76b9c04f3ed23883de6279b4485612e8.tar.gz
kmi-3ace1ddd76b9c04f3ed23883de6279b4485612e8.zip
start trying to boot on visionfive 2
+ Not bootable quite yet. Among other things, I couldn't get the current starfive u-boot fork to boot, so try adding support for booting with precompiled u-boot via the `go` command. Initial testing with qemu shows that this should be possible, and if it works, might be useful in the (far) future with other slightly janky SBCs. Also, NS16550 is 8250-based, and I'm really only using the base 8250, so rename and add visionfive 2 uart to list of compatibles. Visionfive 2 is still completely untested.
Diffstat (limited to 'common/string.c')
-rw-r--r--common/string.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/common/string.c b/common/string.c
index 6685c08..a76c875 100644
--- a/common/string.c
+++ b/common/string.c
@@ -324,3 +324,139 @@ __weak int memcmp(const void *ptr1, const void *ptr2, size_t num)
return (int)(p1[-1] - p2[-1]);
}
+
+/**
+ * Convert ASCII hex character to integer.
+ * Allows both upper- and lowercase letters.
+ *
+ * @param c Character to convert.
+ * @return Corresponding integer value. That is, '1' => 1, '2' => 2, etc.
+ * \c -1 if conversion failed.
+ */
+static int __hexval(char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+
+ if (c >= 'a' && c <= 'f')
+ return c - 'a';
+
+ if (c >= 'A' && c <= 'F')
+ return c - 'A';
+
+ return -1;
+}
+
+/**
+ * Convert string assumed to represent hex
+ * value to corresponding pointer.
+ *
+ * @param s String to convert to value.
+ * @return Corresponding pointer value.
+ */
+static uintptr_t __hexuintptr(const char *s)
+{
+ uintptr_t res = 0;
+ int val = 0;
+ while ((val = __hexval(*(s++))) != -1) {
+ res *= 16;
+ res += val;
+ }
+
+ return res;
+}
+
+/**
+ * Convert ASCII decimal character to integer.
+ *
+ * @param c Character to convert.
+ * @return Corresponding integer value. That is, '1' => 1, '2' => 2, etc.
+ * \c -1 if conversion failed.
+ */
+static int __decval(char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+
+ return -1;
+}
+
+/**
+ * Convert string assumed to represent decimal
+ * value to corresponding pointer.
+ *
+ * @param s String to convert to value.
+ * @return Corresponding pointer value.
+ */
+static uintptr_t __decuintptr(const char *s)
+{
+ uintptr_t res = 0;
+ int val = 0;
+ while ((val = __decval(*(s++))) != -1) {
+ res *= 10;
+ res += val;
+ }
+
+ return res;
+}
+
+/**
+ * Convert ASCII octal character to integer.
+ *
+ * @param c Character to convert.
+ * @return Corresponding integer value. That is, '1' => 1, '2' => 2, etc.
+ * \c -1 if conversion failed.
+ */
+static int __octval(char c)
+{
+ if (c >= '0' && c <= '7')
+ return c - '0';
+
+ return -1;
+}
+
+/**
+ * Convert string assumed to represent octal
+ * value to corresponding pointer.
+ *
+ * @param s String to convert to value.
+ * @return Corresponding pointer value.
+ */
+static uintptr_t __octuintptr(const char *s)
+{
+ uintptr_t res = 0;
+ int val = 0;
+ while ((val = __octval(*(s++))) != -1) {
+ res *= 8;
+ res += val;
+ }
+
+ return res;
+}
+
+uintptr_t strtouintptr(const char *s)
+{
+ if (!s)
+ return 0;
+
+ if (s[0] == 0)
+ return 0;
+
+ if (s[0] == '0') {
+ if (s[1] == 0)
+ return 0;
+
+ if (s[1] == 'x' || s[1] == 'X')
+ return __hexuintptr(s + 2);
+
+ return __octuintptr(s + 1);
+ }
+
+ if (s[0] == '-')
+ return -__decuintptr(s + 1);
+
+ if (s[0] == '+')
+ return __decuintptr(s + 1);
+
+ return __decuintptr(s);
+}