| //===----------------------------------------------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| /// | |
| /// \file | |
| /// Speed translation utilities for termios. | |
| /// | |
| //===----------------------------------------------------------------------===// | |
| #ifndef LLVM_LIBC_SRC_TERMIOS_LINUX_SPEED_UTILS_H | |
| #define LLVM_LIBC_SRC_TERMIOS_LINUX_SPEED_UTILS_H | |
| #include "hdr/termios_macros.h" | |
| #include "hdr/types/speed_t.h" | |
| #include "src/__support/macros/config.h" | |
| namespace LIBC_NAMESPACE_DECL { | |
| constexpr speed_t INVALID_SPEED = ~static_cast<speed_t>(0); | |
| // glibc 2.42 changed the behavior of the termios Bxxx constants: | |
| // - Before glibc 2.42, the Bxxx constants correspond to the kernel speed | |
| // bitmasks | |
| // directly (e.g. B50 = 1). | |
| // - Starting from glibc 2.42, to support arbitrary baud rates numerically, the | |
| // Bxxx constants are defined as their actual integer values (e.g. B50 = 50). | |
| // In this case, we need to translate between the host's numerical speeds and | |
| // the kernel's speed bitmasks. | |
| // - If B50 == 1, then the host uses the kernel's bitmasks directly (no | |
| // translation). | |
| // - If B50 is not 1 (e.g. B50 == 50 in glibc >= 2.42), we apply | |
| // translation. | |
| #if (B50 == 1) | |
| LIBC_INLINE constexpr speed_t encode_speed(speed_t speed) { return speed; } | |
| LIBC_INLINE constexpr speed_t decode_speed(speed_t speed) { return speed; } | |
| #else // Overlay mode with numerical speeds (e.g. glibc) | |
| LIBC_INLINE constexpr speed_t encode_speed(speed_t speed) { | |
| switch (speed) { | |
| case 0: | |
| return 0; | |
| case 50: | |
| return 0000001; | |
| case 75: | |
| return 0000002; | |
| case 110: | |
| return 0000003; | |
| case 134: | |
| return 0000004; | |
| case 150: | |
| return 0000005; | |
| case 200: | |
| return 0000006; | |
| case 300: | |
| return 0000007; | |
| case 600: | |
| return 0000010; | |
| case 1200: | |
| return 0000011; | |
| case 1800: | |
| return 0000012; | |
| case 2400: | |
| return 0000013; | |
| case 4800: | |
| return 0000014; | |
| case 9600: | |
| return 0000015; | |
| case 19200: | |
| return 0000016; | |
| case 38400: | |
| return 0000017; | |
| case 57600: | |
| return 0010001; | |
| case 115200: | |
| return 0010002; | |
| case 230400: | |
| return 0010003; | |
| case 460800: | |
| return 0010004; | |
| case 500000: | |
| return 0010005; | |
| case 576000: | |
| return 0010006; | |
| case 921600: | |
| return 0010007; | |
| case 1000000: | |
| return 0010010; | |
| case 1152000: | |
| return 0010011; | |
| case 1500000: | |
| return 0010012; | |
| case 2000000: | |
| return 0010013; | |
| case 2500000: | |
| return 0010014; | |
| case 3000000: | |
| return 0010015; | |
| case 3500000: | |
| return 0010016; | |
| case 4000000: | |
| return 0010017; | |
| default: | |
| return INVALID_SPEED; | |
| } | |
| } | |
| LIBC_INLINE constexpr speed_t decode_speed(speed_t kernel_speed) { | |
| switch (kernel_speed) { | |
| case 0: | |
| return 0; | |
| case 0000001: | |
| return 50; | |
| case 0000002: | |
| return 75; | |
| case 0000003: | |
| return 110; | |
| case 0000004: | |
| return 134; | |
| case 0000005: | |
| return 150; | |
| case 0000006: | |
| return 200; | |
| case 0000007: | |
| return 300; | |
| case 0000010: | |
| return 600; | |
| case 0000011: | |
| return 1200; | |
| case 0000012: | |
| return 1800; | |
| case 0000013: | |
| return 2400; | |
| case 0000014: | |
| return 4800; | |
| case 0000015: | |
| return 9600; | |
| case 0000016: | |
| return 19200; | |
| case 0000017: | |
| return 38400; | |
| case 0010001: | |
| return 57600; | |
| case 0010002: | |
| return 115200; | |
| case 0010003: | |
| return 230400; | |
| case 0010004: | |
| return 460800; | |
| case 0010005: | |
| return 500000; | |
| case 0010006: | |
| return 576000; | |
| case 0010007: | |
| return 921600; | |
| case 0010010: | |
| return 1000000; | |
| case 0010011: | |
| return 1152000; | |
| case 0010012: | |
| return 1500000; | |
| case 0010013: | |
| return 2000000; | |
| case 0010014: | |
| return 2500000; | |
| case 0010015: | |
| return 3000000; | |
| case 0010016: | |
| return 3500000; | |
| case 0010017: | |
| return 4000000; | |
| default: | |
| return kernel_speed; | |
| } | |
| } | |
| #endif // (B50 == 1) | |
| } // namespace LIBC_NAMESPACE_DECL | |
| #endif // LLVM_LIBC_SRC_TERMIOS_LINUX_SPEED_UTILS_H |