-
Notifications
You must be signed in to change notification settings - Fork 640
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[dev][uart][pl011] Move to common driver #274
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#pragma once | ||
|
||
void pl011_uart_init(int irq, int nr, uintptr_t base); | ||
void pl011_uart_init_early(int nr, uintptr_t base); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
LOCAL_DIR := $(GET_LOCAL_DIR) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please name this dev/uart/pl011 instead of at the top level of dev. |
||
|
||
MODULE := $(LOCAL_DIR) | ||
|
||
MODULE_SRCS += $(LOCAL_DIR)/uart.c | ||
|
||
include make/module.mk |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,8 +12,8 @@ | |
#include <kernel/thread.h> | ||
#include <platform/interrupts.h> | ||
#include <platform/debug.h> | ||
#include <platform/qemu-virt.h> | ||
#include <target/debugconfig.h> | ||
#include <assert.h> | ||
|
||
/* PL011 implementation */ | ||
#define UART_DR (0x00) | ||
|
@@ -37,24 +37,22 @@ | |
#define NUM_UART 1 | ||
|
||
static cbuf_t uart_rx_buf[NUM_UART]; | ||
static uintptr_t uart_base[NUM_UART]; | ||
|
||
static inline uintptr_t uart_to_ptr(unsigned int n) { | ||
switch (n) { | ||
default: | ||
case 0: | ||
return UART_BASE; | ||
} | ||
return uart_base[n]; | ||
} | ||
|
||
static enum handler_return uart_irq(void *arg) { | ||
bool resched = false; | ||
uint port = (uintptr_t)arg; | ||
uint port = (uint)arg; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is an issue with 64bit targets, since its down casting to a smaller size. Perhaps cast it through uintptr_t first, then down to uint. |
||
uintptr_t base = uart_to_ptr(port); | ||
|
||
/* read interrupt status and mask */ | ||
uint32_t isr = UARTREG(base, UART_TMIS); | ||
|
||
if (isr & (1<<4)) { // rxmis | ||
if (isr & ((1<<6) | (1<<4))) { // rtmis, rxmis | ||
UARTREG(base, UART_ICR) = (1<<4); | ||
cbuf_t *rxbuf = &uart_rx_buf[port]; | ||
|
||
/* while fifo is not empty, read chars out of it */ | ||
|
@@ -83,37 +81,38 @@ static enum handler_return uart_irq(void *arg) { | |
return resched ? INT_RESCHEDULE : INT_NO_RESCHEDULE; | ||
} | ||
|
||
void uart_init(void) { | ||
for (size_t i = 0; i < NUM_UART; i++) { | ||
uintptr_t base = uart_to_ptr(i); | ||
void pl011_uart_init(int irq, int nr, uintptr_t base) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To generally be consistent with existing apis, put the number first. |
||
assert(nr < NUM_UART); | ||
uart_base[nr] = base; | ||
// create circular buffer to hold received data | ||
cbuf_initialize(&uart_rx_buf[nr], RXBUF_SIZE); | ||
|
||
// create circular buffer to hold received data | ||
cbuf_initialize(&uart_rx_buf[i], RXBUF_SIZE); | ||
// assumes interrupts are contiguous | ||
register_int_handler(irq, &uart_irq, (void *)nr); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the (void *) is a warning on arm64. Perhaps as before, cast it through uintptr_t first. |
||
|
||
// assumes interrupts are contiguous | ||
register_int_handler(UART0_INT + i, &uart_irq, (void *)i); | ||
// clear all irqs | ||
UARTREG(base, UART_ICR) = 0x3ff; | ||
|
||
// clear all irqs | ||
UARTREG(base, UART_ICR) = 0x3ff; | ||
UARTREG(base, UART_LCRH) = (3<<5) // 8bit mode | ||
| (1<<4); // fifo enable | ||
|
||
// set fifo trigger level | ||
UARTREG(base, UART_IFLS) = 0; // 1/8 rxfifo, 1/8 txfifo | ||
// set fifo trigger level | ||
UARTREG(base, UART_IFLS) = 4 << 3; // 7/8 rxfifo, 1/8 txfifo | ||
|
||
// enable rx interrupt | ||
UARTREG(base, UART_IMSC) = (1<<4); // rxim | ||
// enable rx interrupt | ||
UARTREG(base, UART_IMSC) = (1<<6)|(1<<4); // rtim, rxim | ||
|
||
// enable receive | ||
UARTREG(base, UART_CR) |= (1<<9); // rxen | ||
// enable receive | ||
UARTREG(base, UART_CR) |= (1<<9)|(1<<8)|(1<<0); // rxen, tx_enable, uarten | ||
|
||
// enable interrupt | ||
unmask_interrupt(UART0_INT + i); | ||
} | ||
// enable interrupt | ||
unmask_interrupt(irq); | ||
} | ||
|
||
void uart_init_early(void) { | ||
for (size_t i = 0; i < NUM_UART; i++) { | ||
UARTREG(uart_to_ptr(i), UART_CR) = (1<<8)|(1<<0); // tx_enable, uarten | ||
} | ||
void pl011_uart_init_early(int nr, uintptr_t base) { | ||
assert(nr < NUM_UART); | ||
uart_base[nr] = base; | ||
UARTREG(uart_to_ptr(nr), UART_CR) = (1<<8)|(1<<0); // tx_enable, uarten | ||
} | ||
|
||
int uart_putc(int port, char c) { | ||
|
@@ -132,7 +131,7 @@ int uart_getc(int port, bool wait) { | |
|
||
char c; | ||
if (cbuf_read_char(rxbuf, &c, wait) == 1) { | ||
UARTREG(uart_to_ptr(port), UART_IMSC) = (1<<4); // rxim | ||
UARTREG(uart_to_ptr(port), UART_IMSC) |= (1<<4); // rxim | ||
return c; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,8 +42,8 @@ SMP_CPU_ID_BITS := 8 | |
GLOBAL_DEFINES += \ | ||
BCM2836=1 | ||
|
||
MODULE_SRCS += \ | ||
$(LOCAL_DIR)/uart.c | ||
MODULES += \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use MODULE_DEPS instead of MODULES. MODULES sometimes works but the _DEPS is the correct solution. |
||
dev/pl011 | ||
|
||
else ifeq ($(TARGET),rpi3) | ||
ARCH := arm64 | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,6 @@ MODULE_SRCS += \ | |
$(LOCAL_DIR)/debug.c \ | ||
$(LOCAL_DIR)/platform.c \ | ||
$(LOCAL_DIR)/secondary_boot.S \ | ||
$(LOCAL_DIR)/uart.c | ||
|
||
MEMBASE := 0x40000000 | ||
MEMSIZE ?= 0x08000000 # 512MB | ||
|
@@ -33,6 +32,7 @@ MODULE_DEPS += \ | |
dev/virtio/block \ | ||
dev/virtio/gpu \ | ||
dev/virtio/net \ | ||
dev/pl011 \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be consistent, sort the list of the devs. |
||
|
||
GLOBAL_DEFINES += \ | ||
MEMBASE=$(MEMBASE) \ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the standard license header here.