9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit ab5f5c418fd4e8c41910ed38de0b9c57f8d9433d
parent 567d892277c90238da36880db707143253a0e0f6
Author: Dimitris Papastamos <dimitris.papastamos@arm.com>
Date:   Mon, 15 Oct 2018 13:54:52 +0100

[drivers] Change uart driver implementation from assembly to C

Change-Id: I65701a91e2d669454be313916bfd3d22ecf72340
Signed-off-by: Dimitris Papastamos <dimitris.papastamos@arm.com>

Diffstat:
MMakefile | 3++-
March/arm64/Makefile | 14++++++++++++--
March/arm64/rom-none.c | 3++-
Adrivers/Makefile | 9+++++++++
Adrivers/uart.c | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/uart.h | 6++++++
Mscripts/rules.mk | 1+
Msrc/libc/arch/arm64/_write-none.s | 78+++++-------------------------------------------------------------------------
8 files changed, 135 insertions(+), 77 deletions(-)

diff --git a/Makefile b/Makefile @@ -13,7 +13,7 @@ src: lib bin bin lib: mkdir $@ -src arch/$(ARCH): FORCE +drivers src arch/$(ARCH): FORCE +@cd $@ && $(MAKE) gen: FORCE @@ -22,5 +22,6 @@ gen: FORCE clean: +@cd src && $(MAKE) clean +@cd arch && $(MAKE) clean + +@cd drivers && $(MAKE) clean +@cd test && $(MAKE) clean rm -rf lib bin diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile @@ -1,8 +1,18 @@ PROJECTDIR = ../.. include $(PROJECTDIR)/scripts/rules.mk -ROMOBJS = rom-crt-$(SYS).o rom-$(SYS).o panic.o arch.o $(SRCDIR)/romfw/builtin.o -RAMOBJS = ram-crt-$(SYS).o ram-$(SYS).o panic.o arch.o $(SRCDIR)/ramfw/builtin.o +ROMOBJS = rom-crt-$(SYS).o \ + rom-$(SYS).o panic.o \ + arch.o \ + $(DRVDIR)/uart.o \ + $(SRCDIR)/romfw/builtin.o \ + +RAMOBJS = ram-crt-$(SYS).o \ + ram-$(SYS).o \ + panic.o \ + arch.o \ + $(DRVDIR)/uart.o \ + $(SRCDIR)/ramfw/builtin.o \ TARGET = $(BINDIR)/romfw.bin $(BINDIR)/ramfw.bin LIBS = -lhdl -lrmu -lc diff --git a/arch/arm64/rom-none.c b/arch/arm64/rom-none.c @@ -1,6 +1,7 @@ #include <string.h> #include <rcode.h> +#include <uart.h> /* * We allocate space for 3 nested exceptions, covering @@ -21,7 +22,7 @@ main(void *text, void *ram, size_t ramsiz) fp = (struct trapframe *) (bp + bsssiz); fp += NR_NESTED - 1; wr_sp_r(fp); - _uart_init(); + uartinit(115200); enaabt(); isb(); diff --git a/drivers/Makefile b/drivers/Makefile @@ -0,0 +1,9 @@ +PROJECTDIR=.. +include $(PROJECTDIR)/scripts/rules.mk + +OBJS = uart.o + +all: $(OBJS) + +clean: + rm -f $(OBJS) diff --git a/drivers/uart.c b/drivers/uart.c @@ -0,0 +1,98 @@ +#include <uart.h> +#include <rcode.h> + +#define BASE 0x1c090000 +#define CLK 24000000 + +#define CR 0x30 +#define FBRD 0x28 +#define IBRD 0x24 +#define LCRH 0x2c +#define FR 0x18 +#define RSR_ECR 0x4 +#define DR 0x0 + +#define CR_RTS (1 << 11) +#define CR_RXE (1 << 9) +#define CR_TXE (1 << 8) +#define CR_EN (1 << 0) + +#define LCRH_FEN (1 << 4) +#define LCRH_WLEN_8 (3 << 5) + +#define FR_TXFE (1 << 6) +#define FR_TXFF (1 << 5) +#define FR_RXFE (1 << 4) + +static void +setbaudrate(int baudrate) +{ + char *base = (char *)BASE; + unsigned int div; + + div = (CLK * 4) / baudrate; + outm32(div >> 6, base + IBRD); + outm32(div & 0x3f, base + FBRD); +} + +static void +flush(void) +{ + char *base = (char *)BASE; + + while ((inm32(base + CR) & CR_EN) && + (inm32(base + FR) & FR_TXFE)) + ; +} + +static void +ansism(void) +{ + static const char buf[5] = { 0x1b, '[', '2', '0', 'h' }; + uartwrite(buf, sizeof(buf)); +} + +void +uartinit(int baudrate) +{ + char *base = (char *)BASE; + + outm32(0, base + RSR_ECR); + outm32(0, base + CR); + setbaudrate(baudrate); + outm32(LCRH_WLEN_8 | LCRH_FEN, base + LCRH); + outm32(CR_EN | CR_TXE | CR_RXE, base + CR); + ansism(); + return; +} + +int +uartgetc(void) +{ + char *base = (char *)BASE; + + while (inm32(base + FR) & FR_RXFE) + ; + return inm8(base + DR); +} + +int +uartputc(int c) +{ + char *base = (char *)BASE; + + while (inm32(base + FR) & FR_TXFF) + ; + outm8(c, base + DR); + return c; +} + +void +uartwrite(const char *buf, size_t siz) +{ + size_t i; + + for (i = 0; i < siz; i++) + uartputc(buf[i]); + flush(); +} diff --git a/include/uart.h b/include/uart.h @@ -0,0 +1,6 @@ +#include <stddef.h> + +extern void uartinit(int baudrate); +extern int uartgetc(void); +extern int uartputc(int c); +extern void uartwrite(const char *buf, size_t siz); diff --git a/scripts/rules.mk b/scripts/rules.mk @@ -5,6 +5,7 @@ INCDIR = $(PROJECTDIR)/include LIBDIR = $(PROJECTDIR)/lib BINDIR = $(PROJECTDIR)/bin ARCHDIR = $(PROJECTDIR)/arch/$(ARCH) +DRVDIR = $(PROJECTDIR)/drivers SRCDIR = $(PROJECTDIR)/src SCRIPTDIR= $(PROJECTDIR)/scripts INCLUDES = -I$(INCDIR) -I$(INCDIR)/bits/$(ARCH)/ -I$(INCDIR)/bits/$(SYS) diff --git a/src/libc/arch/arm64/_write-none.s b/src/libc/arch/arm64/_write-none.s @@ -1,81 +1,13 @@ .file "_write-none.s" -BASE = 0x1c090000 -CLK = 24000000 -BAUD = 115200 - -CR = 0x30 -LCR_H = 0x2c -FBRD = 0x28 -IBRD = 0x24 -FR = 0x18 -ECR = 0x04 -DR = 0x0 - -CR_RXE = (1<<9) -CR_TXE = (1<<8) -CR_EN = (1<<0) - -LCR_H_FEN = (1<<4) -LCR_H_WLEN_8 = (3<<5) - -FR_TXFF_BIT = 5 -FR_BUSY_BIT = 3 - .text - .globl _uart_init,_write - -_uart_init: - ldr x0,=BASE - ldr x1,=CLK - ldr x2,=BAUD - - ldr w3,[x0,CR] - mov w4,CR_EN - bic w3, w3, w4 - str w3,[x0,CR] - lsl w1,w1,2 - udiv w2,w1,w2 - lsr w1,w2,6 - str w1,[x0,IBRD] - and w1,w2,0x3f - str w1,[x0,FBRD] - mov w1,LCR_H_FEN|LCR_H_WLEN_8 - str w1,[x0,LCR_H] - str wzr,[x0,ECR] - mov w1,CR_RXE|CR_TXE|CR_EN - str w1,[x0,CR] - - adr x1,ansism - mov x2,5 - b _write - + .globl _write /* * x0 = fd (unused) * x1 = buf * x2 = cnt */ -_write: ldr x3,=BASE - -noready: - ldr w4,[x3,FR] - tbnz w4,FR_TXFF_BIT,noready - - ldrb w4,[x1],#1 - str w4,[x3,DR] - subs x2,x2,#1 - cbnz x2,noready - - mov w5,'\n' - cmp w4,w0 - b.eq busy - ret - -busy: - ldr w2,[x3,FR] - tbnz w2,FR_BUSY_BIT,busy - ret - - .section .rodata -ansism: .byte 0x1b - .ascii "[20h" +_write: + mov x0,x1 + mov x1,x2 + b uartwrite