From 26bda4f32daab696070e50690adb4c29e4a9cd2c Mon Sep 17 00:00:00 2001 From: TuxSH Date: Sat, 11 Jan 2020 01:36:55 +0000 Subject: [PATCH] thermosphere: refactor tegra uart code, etc. --- thermosphere/src/irq.c | 3 - thermosphere/src/main.c | 5 +- .../src/platform/qemu/interrupt_config.h | 18 +- thermosphere/src/platform/qemu/uart.c | 41 +++- thermosphere/src/platform/qemu/uart.h | 5 +- .../src/platform/tegra/interrupt_config.h | 5 + thermosphere/src/platform/tegra/uart.c | 200 ++++++++++++------ thermosphere/src/platform/tegra/uart.h | 93 +++++--- thermosphere/src/platform/uart.h | 34 +-- thermosphere/src/utils.h | 6 + 10 files changed, 261 insertions(+), 149 deletions(-) diff --git a/thermosphere/src/irq.c b/thermosphere/src/irq.c index ec7378b6c..e8385ce7e 100644 --- a/thermosphere/src/irq.c +++ b/thermosphere/src/irq.c @@ -129,9 +129,6 @@ void initIrq(void) configureInterrupt(GIC_IRQID_MAINTENANCE, IRQ_PRIORITY_HOST, true); - for(u32 i=32; i < 256+32; i++) { - configureInterrupt(i, IRQ_PRIORITY_HOST, true); - } recursiveSpinlockUnlockRestoreIrq(&g_irqManager.lock, flags); } diff --git a/thermosphere/src/main.c b/thermosphere/src/main.c index ca91dbd95..00375154e 100644 --- a/thermosphere/src/main.c +++ b/thermosphere/src/main.c @@ -45,8 +45,9 @@ void thermosphereMain(ExceptionStackFrame *frame) initIrq(); if (currentCoreCtx->isBootCore) { - uartInit(DEFAULT_UART, 115200, 0); - uartSetInterruptStatus(DEFAULT_UART, false, false); + uartInit(DEFAULT_UART, BAUD_115200, 0); + uartSetInterruptStatus(DEFAULT_UART, DIRECTION_READ, true); + DEBUG("EL2: core %u reached main first!\n", currentCoreCtx->coreId); } diff --git a/thermosphere/src/platform/qemu/interrupt_config.h b/thermosphere/src/platform/qemu/interrupt_config.h index 35c78cf31..cf6f78bec 100644 --- a/thermosphere/src/platform/qemu/interrupt_config.h +++ b/thermosphere/src/platform/qemu/interrupt_config.h @@ -21,21 +21,21 @@ // For both guest and host #define MAX_NUM_REGISTERED_INTERRUPTS 512 -#define GIC_IRQID_PMU 23 -#define GIC_IRQID_MAINTENANCE 25 -#define GIC_IRQID_NS_PHYS_HYP_TIMER 26 -#define GIC_IRQID_NS_VIRT_TIMER 27 -//#define GIC_IRQID_LEGACY_NFIQ 28 not defined? -#define GIC_IRQID_SEC_PHYS_TIMER 29 -#define GIC_IRQID_NS_PHYS_TIMER 30 -//#define GIC_IRQID_LEGACY_NIRQ 31 not defined? +#define GIC_IRQID_PMU 23 +#define GIC_IRQID_MAINTENANCE 25 +#define GIC_IRQID_NS_PHYS_HYP_TIMER 26 +#define GIC_IRQID_NS_VIRT_TIMER 27 +//#define GIC_IRQID_LEGACY_NFIQ 28 not defined? +#define GIC_IRQID_SEC_PHYS_TIMER 29 +#define GIC_IRQID_NS_PHYS_TIMER 30 +//#define GIC_IRQID_LEGACY_NIRQ 31 not defined? #define GIC_IRQID_NS_VIRT_HYP_TIMER GIC_IRQID_SPURIOUS // SBSA: 28. Unimplemented #define GIC_IRQID_SEC_PHYS_HYP_TIMER GIC_IRQID_SPURIOUS // SBSA: 20. Unimplemented #define GIC_IRQID_SEC_VIRT_HYP_TIMER GIC_IRQID_SPURIOUS // SBSA: 19. Unimplemented -#define GIC_IRQID_UART 33 +#define GIC_IRQID_UART (32 + 1) static inline void initGicV2Pointers(ArmGicV2 *gic) { diff --git a/thermosphere/src/platform/qemu/uart.c b/thermosphere/src/platform/qemu/uart.c index 200f2e774..66fa09021 100644 --- a/thermosphere/src/platform/qemu/uart.c +++ b/thermosphere/src/platform/qemu/uart.c @@ -83,12 +83,11 @@ void uartInit(UartDevice dev, u32 baudRate, u32 flags) uart->icr = PL011_ALL_INTERRUPTS; // Register the interrupt ID - //configureInterrupt(uartGetIrqId(dev), IRQ_PRIORITY_HOST, true); + configureInterrupt(uartGetIrqId(dev), IRQ_PRIORITY_HOST, true); // Enable tx, rx, and uart overall uart->cr = PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN; - uart->imsc = PL011_RTI | PL011_RXI | PL011_RXI; - + //uart->imsc = PL011_RTI | PL011_RXI | PL011_RXI; } void uartWriteData(UartDevice dev, const void *buffer, size_t size) @@ -120,24 +119,48 @@ size_t uartReadDataMax(UartDevice dev, void *buffer, size_t maxSize) volatile PL011UartRegisters *uart = uartGetRegisters(dev); u8 *buf8 = (u8 *)buffer; - size_t i; + size_t count = 0; - for (i = 0; i < maxSize && !(uart->fr & PL011_UARTFR_RXFE); i++) { + for (size_t i = 0; i < maxSize && !(uart->fr & PL011_UARTFR_RXFE); i++) { buf8[i] = uart->dr; + ++count; } - return 1 + i; + return count; } -void uartSetInterruptStatus(UartDevice dev, bool read, bool enable) +ReadWriteDirection uartGetInterruptDirection(UartDevice dev) +{ + volatile PL011UartRegisters *uart = uartGetRegisters(dev); + u32 ret = 0; + + u32 istatus = uart->mis; + if (istatus & (PL011_RTI | PL011_RXI)) { + ret |= DIRECTION_READ; + } + if (istatus & PL011_TXI) { + ret |= DIRECTION_WRITE; + } + + return (ReadWriteDirection)ret; +} + +void uartSetInterruptStatus(UartDevice dev, ReadWriteDirection direction, bool enable) { volatile PL011UartRegisters *uart = uartGetRegisters(dev); - u32 mask = read ? PL011_RTI | PL011_RXI : PL011_RTI; + u32 mask = 0; + if (direction & DIRECTION_READ) { + mask |= PL011_RTI | PL011_RXI; + } + if (direction & DIRECTION_WRITE) { + mask |= PL011_TXI; + } + if (enable) { uart->imsc |= mask; } else { uart->icr = mask; uart->imsc &= ~mask; } -} \ No newline at end of file +} diff --git a/thermosphere/src/platform/qemu/uart.h b/thermosphere/src/platform/qemu/uart.h index ba92a8268..523dea480 100644 --- a/thermosphere/src/platform/qemu/uart.h +++ b/thermosphere/src/platform/qemu/uart.h @@ -132,7 +132,8 @@ void uartInit(UartDevice dev, u32 baudRate, u32 flags); void uartWriteData(UartDevice dev, const void *buffer, size_t size); void uartReadData(UartDevice dev, void *buffer, size_t size); size_t uartReadDataMax(UartDevice dev, void *buffer, size_t maxSize); -void uartSetInterruptStatus(UartDevice dev, bool read, bool enable); +ReadWriteDirection uartGetInterruptDirection(UartDevice dev); +void uartSetInterruptStatus(UartDevice dev, ReadWriteDirection direction, bool enable); static inline u16 uartGetIrqId(UartDevice dev) { @@ -142,4 +143,4 @@ static inline u16 uartGetIrqId(UartDevice dev) default: return GIC_IRQID_SPURIOUS; } -} \ No newline at end of file +} diff --git a/thermosphere/src/platform/tegra/interrupt_config.h b/thermosphere/src/platform/tegra/interrupt_config.h index 1b3b48789..310383d53 100644 --- a/thermosphere/src/platform/tegra/interrupt_config.h +++ b/thermosphere/src/platform/tegra/interrupt_config.h @@ -33,6 +33,11 @@ #define GIC_IRQID_SEC_PHYS_HYP_TIMER GIC_IRQID_SPURIOUS // SBSA: 20. Unimplemented #define GIC_IRQID_SEC_VIRT_HYP_TIMER GIC_IRQID_SPURIOUS // SBSA: 19. Unimplemented +#define GIC_IRQID_UARTA (32 + 36) +#define GIC_IRQID_UARTB (32 + 37) +#define GIC_IRQID_UARTC (32 + 46) +#define GIC_IRQID_UARTD (32 + 90) + static inline void initGicV2Pointers(ArmGicV2 *gic) { gic->gicd = (volatile ArmGicV2Distributor *)0x50041000ull; diff --git a/thermosphere/src/platform/tegra/uart.c b/thermosphere/src/platform/tegra/uart.c index 761dc527c..7664b2069 100644 --- a/thermosphere/src/platform/tegra/uart.c +++ b/thermosphere/src/platform/tegra/uart.c @@ -20,18 +20,27 @@ #include "pinmux.h" #include "gpio.h" #include "car.h" +#include "../../irq.h" -static inline void uart_wait_cycles(uint32_t baud, uint32_t num) +#define UART_BASE 0x70006000 + +static inline volatile tegra_uart_t *uartGetRegisters(UartDevice dev) +{ + static const size_t offsets[] = { 0, 0x40, 0x200, 0x300, 0x400 }; + return (volatile tegra_uart_t *)(UART_BASE + offsets[dev]); +} + +static inline void uartWaitCycles(u32 baud, u32 num) { udelay((num * 1000000 + 16 * baud - 1) / (16 * baud)); } -static inline void uart_wait_syms(uint32_t baud, uint32_t num) +static inline void uartWaitSyms(u32 baud, u32 num) { udelay((num * 1000000 + baud - 1) / baud); } -void uart_config(UartDevice dev) { +static void uartSetPinmuxConfig(UartDevice dev) { volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); switch (dev) { @@ -60,15 +69,15 @@ void uart_config(UartDevice dev) { pinmux->uart4_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN); break; case UART_E: - /* Unused. */ + // Unused. break; default: break; } } -void uart_reset(UartDevice dev) +static void uartReset(UartDevice dev) { - CarDevice uartCarDevs[] = { CARDEVICE_UARTA, CARDEVICE_UARTB, CARDEVICE_UARTC, CARDEVICE_UARTD }; + static const CarDevice uartCarDevs[] = { CARDEVICE_UARTA, CARDEVICE_UARTB, CARDEVICE_UARTC, CARDEVICE_UARTD }; if (dev == UART_B) { gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_SFIO); } else { @@ -81,88 +90,143 @@ void uart_reset(UartDevice dev) gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO); } - uart_config(dev); + uartSetPinmuxConfig(dev); clkrst_reboot(uartCarDevs[dev]); } -void uart_init(UartDevice dev, uint32_t baud, bool inverted) { - volatile tegra_uart_t *uart = uart_get_regs(dev); - /* Wait for idle state. */ - uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE); +// This function blocks until the UART device is in the desired state. +void uartWaitIdle(UartDevice dev, UartVendorStatus status) +{ + volatile tegra_uart_t *uart = uartGetRegisters(dev); - /* Calculate baud rate, round to nearest. */ - uint32_t rate = (8 * baud + 408000000) / (16 * baud); - - /* Setup UART in FIFO mode. */ - uart->UART_IER_DLAB = 0; - uart->UART_MCR = 0; - uart->UART_LCR = (UART_LCR_DLAB | UART_LCR_WD_LENGTH_8); /* Enable DLAB and set word length 8. */ - uart->UART_THR_DLAB = (uint8_t)rate; /* Divisor latch LSB. */ - uart->UART_IER_DLAB = (uint8_t)(rate >> 8); /* Divisor latch MSB. */ - uart->UART_LCR &= ~(UART_LCR_DLAB); /* Disable DLAB. */ - uart->UART_SPR; /* Dummy read. */ - uart_wait_syms(baud, 3); /* Wait for 3 symbols at the new baudrate. */ - - /* Enable FIFO with default settings. */ - uart->UART_IIR_FCR = UART_FCR_FCR_EN_FIFO; - uart->UART_IRDA_CSR = inverted ? 2 : 0; /* Invert TX if needed */ - uart->UART_SPR; /* Dummy read as mandated by TRM. */ - uart_wait_cycles(baud, 3); /* Wait for 3 baud cycles, as mandated by TRM (erratum). */ - - /* Flush FIFO. */ - uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE); /* Make sure there's no data being written in TX FIFO (TRM). */ - uart->UART_IIR_FCR |= UART_FCR_RX_CLR | UART_FCR_TX_CLR; /* Clear TX and RX FIFOs. */ - uart_wait_cycles(baud, 32); /* Wait for 32 baud cycles (TRM, erratum). */ - /* Wait for idle state (TRM). */ - uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE | UART_VENDOR_STATE_RX_IDLE); -} - -/* This function blocks until the UART device is in the desired state. */ -void uart_wait_idle(UartDevice dev, UartVendorStatus status) { - volatile tegra_uart_t *uart = uart_get_regs(dev); - if (status & UART_VENDOR_STATE_TX_IDLE) { - while (!(uart->UART_LSR & UART_LSR_TMTY)) { - /* Wait */ - } + while (!(uart->lsr & UART_LSR_TMTY)); } + if (status & UART_VENDOR_STATE_RX_IDLE) { - while (uart->UART_LSR & UART_LSR_RDR) { - /* Wait */ - } + while (uart->lsr & UART_LSR_RDR); } } -void uart_send(UartDevice dev, const void *buf, size_t len) { - volatile tegra_uart_t *uart = uart_get_regs(dev); +void uartInit(UartDevice dev, u32 baud, u32 flags) +{ + volatile tegra_uart_t *uart = uartGetRegisters(dev); + bool inverted = (flags & BIT(0)) != 0; - for (size_t i = 0; i < len; i++) { - while (!(uart->UART_LSR & UART_LSR_THRE)) { - /* Wait until it's possible to send data. */ - } - uart->UART_THR_DLAB = *((const uint8_t *)buf + i); + // Set pinmux, gpio, clock + uartReset(dev); + + // Wait for idle state. + uartWaitIdle(dev, UART_VENDOR_STATE_TX_IDLE); + + // Calculate baud rate, round to nearest. + u32 rate = (8 * baud + 408000000) / (16 * baud); + + uart->lcr &= ~UART_LCR_DLAB; // Disable DLAB. + uart->ier = 0; // Disable all interrupts. + uart->mcr = 0; + + // Setup UART in FIFO mode + uart->lcr = UART_LCR_DLAB | UART_LCR_WD_LENGTH_8; // Enable DLAB and set word length 8. + uart->dll = (u8)rate; // Divisor latch LSB. + uart->dlh = (u8)(rate >> 8); // Divisor latch MSB. + uart->lcr &= ~UART_LCR_DLAB; // Disable DLAB. + uart->spr; // Dummy read. + uartWaitSyms(baud, 3); // Wait for 3 symbols at the new baudrate. + + // Enable FIFO with default settings. + uart->fcr = UART_FCR_FCR_EN_FIFO; + uart->irda_csr = inverted ? UART_IRDA_CSR_INVERT_TXD : 0; // Invert TX if needed + uart->spr; // Dummy read as mandated by TRM. + uartWaitCycles(baud, 3); // Wait for 3 baud cycles, as mandated by TRM (erratum). + + // Flush FIFO. + uartWaitIdle(dev, UART_VENDOR_STATE_TX_IDLE); // Make sure there's no data being written in TX FIFO (TRM). + uart->fcr |= UART_FCR_RX_CLR | UART_FCR_TX_CLR; // Clear TX and RX FIFOs. + uartWaitCycles(baud, 32); // Wait for 32 baud cycles (TRM, erratum). + + // Wait for idle state (TRM). + uartWaitIdle(dev, UART_VENDOR_STATE_TX_IDLE | UART_VENDOR_STATE_RX_IDLE); + + // Set scratch register to 0. We'll use it to backup write-only IER later + uart->spr = 0; + + // Register the interrupt ID + configureInterrupt(uartGetIrqId(dev), IRQ_PRIORITY_HOST, true); +} + +void uartWriteData(UartDevice dev, const void *buffer, size_t size) +{ + volatile tegra_uart_t *uart = uartGetRegisters(dev); + const u8 *buf8 = (const u8 *)buffer; + + for (size_t i = 0; i < size; i++) { + while (!(uart->lsr & UART_LSR_THRE)); // Wait until it's possible to send data. + uart->thr = buf8[i]; } } -void uart_recv(UartDevice dev, void *buf, size_t len) { - volatile tegra_uart_t *uart = uart_get_regs(dev); +void uartReadData(UartDevice dev, void *buffer, size_t size) +{ + volatile tegra_uart_t *uart = uartGetRegisters(dev); + u8 *buf8 = (u8 *)buffer; - for (size_t i = 0; i < len; i++) { - while (!(uart->UART_LSR & UART_LSR_RDR)) { - /* Wait until it's possible to receive data. */ - } - *((uint8_t *)buf + i) = uart->UART_THR_DLAB; + for (size_t i = 0; i < size; i++) { + while (!(uart->lsr & UART_LSR_RDR)) // Wait until it's possible to receive data. + buf8[i] = uart->rbr; } } -size_t uart_recv_max(UartDevice dev, void *buf, size_t max_len) { - volatile tegra_uart_t *uart = uart_get_regs(dev); - size_t i; +size_t uartReadDataMax(UartDevice dev, void *buffer, size_t maxSize) +{ + volatile tegra_uart_t *uart = uartGetRegisters(dev); + u8 *buf8 = (u8 *)buffer; + size_t count = 0; - for (i = 0; i < max_len && (uart->UART_LSR & UART_LSR_RDR); i++) { - *((uint8_t *)buf + i) = uart->UART_THR_DLAB; + for (size_t i = 0; i < maxSize && (uart->lsr & UART_LSR_RDR); i++) { + buf8[i] = uart->rbr; + ++count; } - return 1 + i; + return count; +} + +ReadWriteDirection uartGetInterruptDirection(UartDevice dev) +{ + volatile tegra_uart_t *uart = uartGetRegisters(dev); + u32 ret = 0; + + u32 iir = uart->iir & 0xF; + + if (iir == 8 || iir == 12) { + // Data ready or data timeout + ret |= DIRECTION_READ; + } else if (iir == 2) { + // TX FIFO empty + ret |= DIRECTION_WRITE; + } + + return (ReadWriteDirection)ret; +} + +void uartSetInterruptStatus(UartDevice dev, ReadWriteDirection direction, bool enable) +{ + volatile tegra_uart_t *uart = uartGetRegisters(dev); + + u32 mask = 0; + if (direction & DIRECTION_READ) { + mask |= UART_IER_IE_RX_TIMEOUT | UART_IER_IE_RHR; + } + if (direction & DIRECTION_WRITE) { + mask |= UART_IER_IE_THR; + } + + if (enable) { + uart->spr |= mask; + uart->ier = uart->spr; + } else { + uart->spr &= ~mask; + uart->ier = uart->spr; + } } diff --git a/thermosphere/src/platform/tegra/uart.h b/thermosphere/src/platform/tegra/uart.h index 66b34e4c8..70782224e 100644 --- a/thermosphere/src/platform/tegra/uart.h +++ b/thermosphere/src/platform/tegra/uart.h @@ -18,18 +18,17 @@ #pragma once #include "../../utils.h" - -#define UART_BASE 0x70006000 - -#define BAUD_115200 115200 +#include "interrupt_config.h" /* UART devices */ -typedef enum { +typedef enum UartDevice { UART_A = 0, UART_B = 1, UART_C = 2, UART_D = 3, UART_E = 4, + + UART_MAX = UART_E, // Treat UART_E as if it didn't exist } UartDevice; /* 36.3.12 UART_VENDOR_STATUS_0_0 */ @@ -123,6 +122,17 @@ typedef enum { UART_FCR_RX_TRIG_FIFO_COUNT_GREATER_16 = 3 << 6, } UartFifoControl; +/* 36.3.2 UART_IER_DLAB_0_0 */ +typedef enum { + UART_IER_IE_RHR = 1 << 0, /* Interrupt enable for Received Data Interrupt */ + UART_IER_IE_THR = 1 << 1, /* Interrupt enable for Transmitter Holding Register Empty interrupt */ + UART_IER_IE_RXS = 1 << 2, /* Interrupt enable for Receiver Line Status Interrupt */ + UART_IER_IE_MSI = 1 << 3, /* Interrupt enable for Modem Status Interrupt */ + UART_IER_IE_RX_TIMEOUT = 1 << 4, /* Interrupt enable for RX FIFO timeout */ + UART_IER_IE_EORD = 1 << 5, /* Interrupt enable for Interrupt Enable for End of Received Data */ + +} UartInterruptEnable; + /* 36.3.3 UART_IIR_FCR_0 */ typedef enum { UART_IIR_IS_STA = 1 << 0, /* Interrupt Pending if ZERO */ @@ -139,32 +149,57 @@ typedef enum { UART_IIR_MODE_16550 = 1 << 6, } UartInterruptIdentification; +/* 36.3.9 UART_IRDA_CSR_0 */ +typedef enum { + UART_IRDA_CSR_INVERT_RXD = 1 << 0, + UART_IRDA_CSR_INVERT_TXD = 1 << 1, + UART_IRDA_CSR_INVERT_CTS = 1 << 2, + UART_IRDA_CSR_INVERT_RTS = 1 << 3, + + UART_IRDA_CSR_PWT_A_BAUD_PULSE_3_14 = 0 << 6, + UART_IRDA_CSR_PWT_A_BAUD_PULSE_4_14 = 1 << 6, + UART_IRDA_CSR_SIR_A = 1 << 7, +} UartIrDAPulseCodingCSR; + typedef struct { - uint32_t UART_THR_DLAB; - uint32_t UART_IER_DLAB; - uint32_t UART_IIR_FCR; - uint32_t UART_LCR; - uint32_t UART_MCR; - uint32_t UART_LSR; - uint32_t UART_MSR; - uint32_t UART_SPR; - uint32_t UART_IRDA_CSR; - uint32_t UART_RX_FIFO_CFG; - uint32_t UART_MIE; - uint32_t UART_VENDOR_STATUS; - uint8_t _0x30[0x0C]; - uint32_t UART_ASR; + union { + // UART_THR_DLAB_0 + u32 thr; + u32 rbr; + u32 dll; + }; + union { + // UART_IER_DLAB_0 + u32 ier; + u32 dlh; + }; + union { + // UART_IIR_FCR_0 + u32 iir; + u32 fcr; + }; + u32 lcr; + u32 mcr; + u32 lsr; + u32 msr; + u32 spr; + u32 irda_csr; + u32 rx_fifo_cfg; + u32 mie; + u32 vendor_status; + u8 _0x30[0x0C]; + u32 asr; } tegra_uart_t; -void uart_config(UartDevice dev); -void uart_reset(UartDevice dev); -void uart_init(UartDevice dev, uint32_t baud, bool inverted); -void uart_wait_idle(UartDevice dev, UartVendorStatus status); -void uart_send(UartDevice dev, const void *buf, size_t len); -void uart_recv(UartDevice dev, void *buf, size_t len); -size_t uart_recv_max(UartDevice dev, void *buf, size_t max_len); +void uartInit(UartDevice dev, u32 baud, u32 flags); +void uartWriteData(UartDevice dev, const void *buffer, size_t size); +void uartReadData(UartDevice dev, void *buffer, size_t size); +size_t uartReadDataMax(UartDevice dev, void *buffer, size_t maxSize); +ReadWriteDirection uartGetInterruptDirection(UartDevice dev); +void uartSetInterruptStatus(UartDevice dev, ReadWriteDirection direction, bool enable); -static inline volatile tegra_uart_t *uart_get_regs(UartDevice dev) { - static const size_t offsets[] = {0, 0x40, 0x200, 0x300, 0x400}; - return (volatile tegra_uart_t *)(UART_BASE + offsets[dev]); +static inline u16 uartGetIrqId(UartDevice dev) +{ + static const u16 irqIds[] = { GIC_IRQID_UARTA, GIC_IRQID_UARTB, GIC_IRQID_UARTC, GIC_IRQID_UARTD }; + return dev < UART_MAX ? irqIds[dev] : GIC_IRQID_SPURIOUS; } diff --git a/thermosphere/src/platform/uart.h b/thermosphere/src/platform/uart.h index 8d5dff798..c2ba437c4 100644 --- a/thermosphere/src/platform/uart.h +++ b/thermosphere/src/platform/uart.h @@ -16,39 +16,19 @@ #pragma once -#if PLATFORM_TEGRA -// TODO +#define BAUD_115200 115200 -/*#include "tegra/uart.h" +#if PLATFORM_TEGRA + +#include "tegra/uart.h" #define DEFAULT_UART UART_C -#define DEFAULT_UARTINV_STATUS true - -static inline void uartInit(u32 baudRate) -{ - uart_reset(DEFAULT_UART); - uart_init(DEFAULT_UART, baudRate, DEFAULT_UARTINV_STATUS); -} - -static inline void uartWriteData(const void *buffer, size_t size) -{ - uart_send(DEFAULT_UART, buffer, size); -} - -static inline void uartReadData(void *buffer, size_t size) -{ - uart_recv(DEFAULT_UART, buffer, size); -} - -static inline size_t uartReadDataMax(void *buffer, size_t maxSize) -{ - return uart_recv_max(DEFAULT_UART, buffer, maxSize); -} -*/ +#define DEFAULT_UART_FLAGS 1 #elif defined(PLATFORM_QEMU) #define DEFAULT_UART UART_A +#define DEFAULT_UART_FLAGS 0 #include "qemu/uart.h" @@ -56,4 +36,4 @@ static inline size_t uartReadDataMax(void *buffer, size_t maxSize) #error "Error: platform not defined" -#endif \ No newline at end of file +#endif diff --git a/thermosphere/src/utils.h b/thermosphere/src/utils.h index 5ff5a2909..13cf31d15 100644 --- a/thermosphere/src/utils.h +++ b/thermosphere/src/utils.h @@ -56,6 +56,12 @@ static inline u##sz __##op##sz(u##sz n)\ _DECLARE_ASM_ARITHMETIC_UNARY_HELPER64(rbit) _DECLARE_ASM_ARITHMETIC_UNARY_HELPER32(rbit) +typedef enum ReadWriteDirection { + DIRECTION_READ = BIT(0), + DIRECTION_WRITE = BIT(1), + DIRECTION_READWRITE = DIRECTION_READ | DIRECTION_WRITE, +} ReadWriteDirection; + static inline void __dmb_sy(void) { __asm__ __volatile__ ("dmb sy" ::: "memory");