diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2023-05-29 21:31:09 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2023-05-29 21:31:09 +0300 |
| commit | 3ace1ddd76b9c04f3ed23883de6279b4485612e8 (patch) | |
| tree | 2f4af69d70967c2455cb83d8c18a5416c8d1b54d /common/string.c | |
| parent | b7f53b9a9001708dea5303faf52f1b508eefb712 (diff) | |
| download | kmi-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.c | 136 |
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); +} |
