Basic UART communications
This commit is contained in:
parent
6e2611ab74
commit
1f25cc23da
2
.idea/editor.xml
generated
2
.idea/editor.xml
generated
@ -139,7 +139,7 @@
|
|||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNotAllPathsReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNotAllPathsReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppObjectMemberMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppObjectMemberMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppOutParameterMustBeWritten/@EntryIndexedValue" value="WARNING" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppOutParameterMustBeWritten/@EntryIndexedValue" value="WARNING" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConst/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConstPtrOrRef/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConstPtrOrRef/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNamesMismatch/@EntryIndexedValue" value="HINT" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNamesMismatch/@EntryIndexedValue" value="HINT" type="string" />
|
||||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
|
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
|
||||||
|
|||||||
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="CppParameterMayBeConst" enabled="false" level="HINT" enabled_by_default="false" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
11
src/kernel/common.h
Normal file
11
src/kernel/common.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef COMMON_H
|
||||||
|
#define COMMON_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a kernel panic message through the UART and hang the core.
|
||||||
|
* @param format The format of the message
|
||||||
|
* @param ... The parameters of the message
|
||||||
|
*/
|
||||||
|
void panic(const char *format, ...);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,46 +1,12 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* Filename: kernel.c
|
|
||||||
*
|
|
||||||
* Description: Kernel entry point
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 2026-02-16 10:13:30 PM
|
|
||||||
* Revision: none
|
|
||||||
* Compiler: gcc
|
|
||||||
*
|
|
||||||
* Author: William Nolin,
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "syscon.h"
|
#include "syscon.h"
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
unsigned char *uart = (unsigned char *)0x10000000;
|
#define ARCH "RISC-V 64"
|
||||||
void putchar(char c) {
|
|
||||||
*uart = c;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void print(const char * str) {
|
|
||||||
while(*str != '\0') {
|
|
||||||
putchar(*str);
|
|
||||||
str++;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void kmain(void) {
|
void kmain(void) {
|
||||||
power_off();
|
uart_init();
|
||||||
|
uart_printf("Hello world, %s!\n", ARCH);
|
||||||
|
|
||||||
// print("Hello world!\r\n");
|
power_off();
|
||||||
// while(1) {
|
|
||||||
// // Read input from the UART
|
|
||||||
// putchar(*uart);
|
|
||||||
// }
|
|
||||||
// return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
src/kernel/riscv64/common.c
Normal file
21
src/kernel/riscv64/common.c
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "../common.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "../uart.h"
|
||||||
|
|
||||||
|
void panic(const char *format, ...) {
|
||||||
|
uart_puts("Kernel panic!");
|
||||||
|
uart_puts("Reason:");
|
||||||
|
|
||||||
|
va_list args = nullptr;
|
||||||
|
va_start(args, format);
|
||||||
|
|
||||||
|
// Print the reason
|
||||||
|
uart_vprintf(format, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
// Hang
|
||||||
|
asm volatile("wfi");
|
||||||
|
}
|
||||||
@ -1,13 +1,16 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "../../syscon.h"
|
#include "../../syscon.h"
|
||||||
|
#include "../../uart.h"
|
||||||
|
|
||||||
// QEMU exposes a syscon-compatible device at address 0x1000000
|
// QEMU exposes a syscon-compatible device at address 0x1000000
|
||||||
#define SYSCON_ADDR 0x100000
|
#define SYSCON_ADDR 0x100000
|
||||||
|
|
||||||
void power_off() {
|
void power_off() {
|
||||||
|
uart_puts("Power off requested");
|
||||||
*(uint32_t *) SYSCON_ADDR = 0x5555;
|
*(uint32_t *) SYSCON_ADDR = 0x5555;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reboot() {
|
void reboot() {
|
||||||
|
uart_puts("Reboot requested");
|
||||||
*(uint32_t *) SYSCON_ADDR = 0x7777;
|
*(uint32_t *) SYSCON_ADDR = 0x7777;
|
||||||
}
|
}
|
||||||
|
|||||||
81
src/kernel/riscv64/qemu/uart.c
Normal file
81
src/kernel/riscv64/qemu/uart.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include "../../uart.h"
|
||||||
|
|
||||||
|
// QEMU emulates the NS16550A UART
|
||||||
|
// The UART is memory mapped at 0x1000000
|
||||||
|
#define UART_ADDR 0x10000000
|
||||||
|
|
||||||
|
void uart_init() {
|
||||||
|
volatile uint8_t *ptr = (uint8_t *) UART_ADDR;
|
||||||
|
|
||||||
|
// Set the word length to 8 bits
|
||||||
|
ptr[3] = 0b11;
|
||||||
|
|
||||||
|
// Enable FIFO
|
||||||
|
ptr[2] = 0b1;
|
||||||
|
|
||||||
|
// Enable receiver buffer interrupts
|
||||||
|
ptr[1] = 0b1;
|
||||||
|
|
||||||
|
// For real hardware, we would need to set a baud rate
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_putchar(const char c) {
|
||||||
|
*(uint8_t *) UART_ADDR = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uart_print(const char *str) {
|
||||||
|
while (*str) {
|
||||||
|
uart_putchar(*str);
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_puts(const char *line) {
|
||||||
|
uart_print(line);
|
||||||
|
uart_putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic implementation of printf supporting the following formats:
|
||||||
|
// - c: Character
|
||||||
|
// - s: String of characters
|
||||||
|
// - %: Literal '%'
|
||||||
|
void uart_vprintf(const char *restrict format, va_list args) {
|
||||||
|
while (*format) {
|
||||||
|
if (*format == '%') {
|
||||||
|
// Ignore this character as it indicates the format of a parameter
|
||||||
|
format++;
|
||||||
|
if (!*format) {
|
||||||
|
// There is nothing after '%'
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*format) {
|
||||||
|
case 'c': // Character
|
||||||
|
uart_putchar(va_arg(args, int));
|
||||||
|
break;
|
||||||
|
case 's': // String
|
||||||
|
uart_print(va_arg(args, char*));
|
||||||
|
break;
|
||||||
|
case '%': // Literal '%'
|
||||||
|
uart_putchar('%');
|
||||||
|
break;
|
||||||
|
default: // Unsupported format
|
||||||
|
uart_putchar('%');
|
||||||
|
uart_putchar(*format);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uart_putchar(*format);
|
||||||
|
}
|
||||||
|
|
||||||
|
format++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_printf(const char *restrict format, ...) {
|
||||||
|
va_list args = nullptr;
|
||||||
|
va_start(args, format);
|
||||||
|
uart_vprintf(format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
@ -1,3 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by william on 2026-02-21.
|
|
||||||
//
|
|
||||||
34
src/kernel/uart.h
Normal file
34
src/kernel/uart.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef UART_H
|
||||||
|
#define UART_H
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/** Initializes a UART device. */
|
||||||
|
void uart_init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a character to the UART.
|
||||||
|
* @param c The character to put
|
||||||
|
*/
|
||||||
|
void uart_putchar(char c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a line to the UART.
|
||||||
|
* @param line The line to put
|
||||||
|
*/
|
||||||
|
void uart_puts(const char *line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a string to the UART following a format.
|
||||||
|
* @param format The format of the string
|
||||||
|
* @param args The parameters of the string
|
||||||
|
*/
|
||||||
|
void uart_vprintf(const char *restrict format, va_list args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a string to the UART following a format.
|
||||||
|
* @param format The format of the string
|
||||||
|
* @param ... The parameters of the string
|
||||||
|
*/
|
||||||
|
void uart_printf(const char *restrict format, ...);
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Reference in New Issue
Block a user