From 3ace1ddd76b9c04f3ed23883de6279b4485612e8 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Mon, 29 May 2023 21:31:09 +0300 Subject: 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. --- common/string.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) (limited to 'common/string.c') 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); +} -- cgit v1.3