Update code due to new rules

This commit is contained in:
Ilja Kartašov 2020-01-15 10:56:04 +01:00
parent 6c4dba0929
commit a0c215e954
34 changed files with 614 additions and 239 deletions

View File

@ -1 +1 @@
Elias Löwe <elias@lowenware.com> Ilja Kartaschoff <ik@lowenware.com>

View File

@ -1,2 +0,0 @@
# Lion's Share License -> LSL
# Löwenware Software Distribution -> LSD

39
LICENSE.md Normal file
View File

@ -0,0 +1,39 @@
# License
Leos (the "Software") is an intellectual property of Löwenware s.r.o.
distributed under terms of [Attribution-NoDerivatives 4.0 International](https://creativecommons.org/licenses/by-nd/4.0/legalcode)
**(CC BY-ND 4.0)** license.
## Highlights
Information below highlights only key features and terms of the
[license](https://creativecommons.org/licenses/by-nd/4.0/legalcode). It is
recommended to read its full text before using licensed Software.
### You are free to:
**Share** — copy and redistribute the Software in any medium or format
for any purpose, even commercially. The licensor cannot revoke these freedoms
as long as you follow the license terms.
### Under the following terms:
**Attribution** — You must give appropriate credit, provide a link to the license,
and indicate if changes were made. You may do so in any reasonable manner, but
not in any way that suggests the licensor endorses you or your use.
**NoDerivatives** — If you remix, transform, or build upon the Software, you may
not distribute the modified material.
**No additional restrictions** — You may not apply legal terms or technological
measures that legally restrict others from doing anything the license permits.
### Disclaimer
The Software is provided "AS IS" without warranty of any kind. In no
event shall the authors or copyright holders be liable for any claim, damages
or other liability, whether out of or in connection with the Software or its
usage.
The license may not give you all of the permissions necessary for your
intended use. For example, other rights such as publicity, privacy,
or moral rights may limit how you use the material.

View File

@ -1,3 +1,88 @@
# Löwe OS # Leos
Operating System for ARMv8 (aarch64) architecture. Operating System for ARMv8 (aarch64) Architecture
* [The Idea](#The Idea)
* [Hardware](#Hardware)
* [Documentation](#Documentation)
* [Compilation](#Compilation)
* [Run](#Run)
* [Debug](#Debug)
* [Roadmap](#Roadmap)
* [Contribution](#Contribution)
---
## The Idea
Löwe OS is being developed to be a lightweight desktop operating system for
ARM-based computers, tablets, mobile phones etc. Here are some concepts behind
it:
1. The OS is free with open source codes, distributed under terms of [CC BY-ND 4.0](LICENSE.md).
2. The OS will have POSIX-compliant API.
3. The OS will include graphical system, shell and generic utilities as a part
of it, being designed to work as a solid product.
4. The OS will respect user's privacy and will not track his/her actions and data.
5. The OS will stive to be secure and robust.
## Hardware
Early development is going for **Raspberry PI3** board and its emulation using
**QEMU**.
## Documentation
* [Project structure](docs/project-structure.md)
* [Naming convention](docs/naming-convention.md)
* [Task scheduling](docs/task-scheduling.md)
* [Memory management](docs/memory-management.md)
## Compilation
To compile Löwe OS run `make` from repository root, make sure
[Clang](https://clang.llvm.org/) compiler is installed on your system.
```
$ make
```
Output files will be stored inside newly created `build` folder.
## Run
To run Löwe OS on QEMU, execute `make run` command for the repository root.
To run Löwe OS on Raspberry PI3, follow these steps:
1. Compile project and copy `build/kernel8.img` and `config.txt` files to
Micro SD card
2. Make sure latest boot code is installed on the SD card
3. Insert SD card into your Raspberry PI3 and power it up
## Debug
If you have `gdb-multiarch` and **QEMU** installed, then debugging should be as
easy as `make debug`.
## Roadmap
1. Generic kernel features:
[x] Loadable Kernel file
[x] UART logging
[x] Memory pages avalability bitmap
[x] Interrupt vectors table
[x] Basic task scheduler
[ ] Context switching
[ ] Memory Mapping Unit
2. Input/output:
[ ] Graphical driver
[ ] USB driver
[ ] Keyboard input driver
[ ] Mouse input driver
3. Graphical system
4. Shell and utilities
5. Networking
6. Sound system
## Contribution

View File

View File

View File

0
docs/task-scheduling.md Normal file
View File

View File

@ -22,16 +22,19 @@ INCS += -I./
LD_SCRIPT = aarch64/aarch64.ld LD_SCRIPT = aarch64/aarch64.ld
SOURCE_FILES = \ SOURCE_FILES = \
aarch64/boot.S \ aarch64/aarch64_boot.S \
aarch64/aarch64.S \ aarch64/aarch64.S \
\ \
core/main.c \ leos/irq.c \
core/irq.c \ leos/leos.c \
core/timer.c \ leos/log.c \
core/log.c \ leos/memory.c \
leos/scheduler.c \
leos/task.c \
\ \
device/uart/uart_mini.c \ drivers/timer/timer.c \
device/uart/uart_qemu.c \ drivers/uart/uart_mini.c \
drivers/uart/uart_qemu.c \
SOURCE_LIST := $(wildcard $(SOURCE_FILES)) SOURCE_LIST := $(wildcard $(SOURCE_FILES))
OBJECT_FILES := $(addsuffix .o, $(addprefix $(BUILD_DIR), ${SOURCE_LIST})) OBJECT_FILES := $(addsuffix .o, $(addprefix $(BUILD_DIR), ${SOURCE_LIST}))

View File

@ -1,53 +1,61 @@
#include "aarch64_irq.h" #include "AArch64_irq.h"
.globl aarch64_init .globl AArch64_init
aarch64_init: AArch64_init:
/* set vector table */ /* set vector table */
adr x0, aarch64_vectors adr x0, AArch64_vectors
msr vbar_el1, x0 msr vbar_el1, x0
mov x0, 0 mov x0, 0
ret ret
.globl aarch64_get_el .globl AArch64_getEL
aarch64_get_el: AArch64_getEL:
mrs x0, CurrentEL mrs x0, CurrentEL
lsr x0, x0, 0x02 lsr x0, x0, 0x02
ret ret
.globl aarch64_get32r .globl AArch64_getReg32
aarch64_get32r: AArch64_get32r:
ldr w0, [x0] ldr w0, [x0]
ret ret
.globl aarch64_set32r .globl AArch64_setReg32
aarch64_set32r: AArch64_set32r:
str w1, [x0] str w1, [x0]
ret ret
.globl aarch64_delay .globl AArch64_idle
aarch64_delay: AArch64_idle:
subs x0, x0, 1 subs x0, x0, 1
bne aarch64_delay bne AArch64_delay
ret ret
.globl aarch64_irq_vector_init /*
irq_vector_init: .globl AArch64_initIRQVector
AArch64_initIRQVector:
ret ret
*/
.globl aarch64_irq_enable .globl AArch64_enableIRQ
aarch64_irq_enable: AArch64_enableIRQ:
msr daifclr, 2 msr daifclr, 2
ret ret
.globl aarch64_irq_disable .globl AArch64_disableIRQ
aarch64_irq_disable: AArch64_disableIRQ:
msr daifset, 2 msr daifset, 2
ret ret
.globl AArch64_memzero
AArch64_memzero:
str xzr, [x0], 8
subs x1, x1, 8
b.gt AArch64_memzero
ret
/* Exceptions Vector Table /* Exceptions Vector Table
* */ * */
.macro KERNEL_ENTER .macro SAVE_REGISTERS
sub sp, sp, 256 sub sp, sp, 256
stp x0, x1, [sp, 16 * 0] stp x0, x1, [sp, 16 * 0]
stp x2, x3, [sp, 16 * 1] stp x2, x3, [sp, 16 * 1]
@ -64,26 +72,36 @@ aarch64_irq_disable:
stp x24, x25, [sp, 16 * 12] stp x24, x25, [sp, 16 * 12]
stp x26, x27, [sp, 16 * 13] stp x26, x27, [sp, 16 * 13]
stp x28, x29, [sp, 16 * 14] stp x28, x29, [sp, 16 * 14]
str x30, [sp, 16 * 15]
mrs x22, elr_el1
mrs x23, spsr_el1
stp x30, x22, [sp, 16 * 15]
str x23, [sp, 16 * 16]
.endm .endm
.macro KERNEL_LEAVE .macro LOAD_REGISTERS
ldp x0, x1, [sp, 16 * 0] ldr x23, [sp, 16 * 16]
ldp x2, x3, [sp, 16 * 1] ldp x30, x22, [sp, 16 * 15]
ldp x4, x5, [sp, 16 * 2]
ldp x6, x7, [sp, 16 * 3] msr elr_el1, x22
ldp x8, x9, [sp, 16 * 4] msr spsr_el1, x23
ldp x10, x11, [sp, 16 * 5]
ldp x12, x13, [sp, 16 * 6]
ldp x14, x15, [sp, 16 * 7]
ldp x16, x17, [sp, 16 * 8]
ldp x18, x19, [sp, 16 * 9]
ldp x20, x21, [sp, 16 * 10]
ldp x22, x23, [sp, 16 * 11]
ldp x24, x25, [sp, 16 * 12]
ldp x26, x27, [sp, 16 * 13]
ldp x28, x29, [sp, 16 * 14] ldp x28, x29, [sp, 16 * 14]
ldr x30, [sp, 16 * 15] ldp x26, x27, [sp, 16 * 13]
ldp x24, x25, [sp, 16 * 12]
ldp x22, x23, [sp, 16 * 11]
ldp x20, x21, [sp, 16 * 10]
ldp x18, x19, [sp, 16 * 9]
ldp x16, x17, [sp, 16 * 8]
ldp x14, x15, [sp, 16 * 7]
ldp x12, x13, [sp, 16 * 6]
ldp x10, x11, [sp, 16 * 5]
ldp x8, x9, [sp, 16 * 4]
ldp x6, x7, [sp, 16 * 3]
ldp x4, x5, [sp, 16 * 2]
ldp x2, x3, [sp, 16 * 1]
ldp x0, x1, [sp, 16 * 0]
add sp, sp, 256 add sp, sp, 256
.endm .endm
@ -93,11 +111,11 @@ aarch64_irq_disable:
.endm .endm
.macro EXCEPTION_FALLBACK EID .macro EXCEPTION_FALLBACK EID
KERNEL_ENTER SAVE_REGISTERS
mov x0, \EID mov x0, \EID
mrs x1, esr_el1 mrs x1, esr_el1
mrs x2, elr_el1 mrs x2, elr_el1
bl k_irq_fallback bl IRQ_fallback
b die b die
.endm .endm
@ -105,8 +123,8 @@ die:
b die b die
.align 11 .align 11
.globl aarch64_vectors .globl AArch64_vectors
aarch64_vectors: AArch64_vectors:
/* EL1t */ /* EL1t */
VECTOR_ENTRY el1t_sync VECTOR_ENTRY el1t_sync
VECTOR_ENTRY el1t_irq VECTOR_ENTRY el1t_irq
@ -144,9 +162,12 @@ el1h_sync:
EXCEPTION_FALLBACK EL1h_SYNC EXCEPTION_FALLBACK EL1h_SYNC
el1h_irq: el1h_irq:
KERNEL_ENTER SAVE_REGISTERS
bl k_irq_handler bl IRQ_onInterrupt
KERNEL_LEAVE cbz x0, load_regs
mov sp, x0 /* task context must be switched */
load_regs:
LOAD_REGISTERS
eret eret
el1h_fiq: el1h_fiq:
@ -179,3 +200,4 @@ el0_32_fiq:
el0_32_error: el0_32_error:
EXCEPTION_FALLBACK EL0_32_ERROR EXCEPTION_FALLBACK EL0_32_ERROR

View File

@ -20,24 +20,27 @@
#include "aarch64_irq.h" #include "aarch64_irq.h"
extern unsigned int extern unsigned int
aarch64_init(void); AArch64_init(void);
extern unsigned int extern unsigned int
aarch64_get_el(void); AArch64_getEL(void);
extern unsigned int extern unsigned int
aarch64_get32r(unsigned long reg); AArch64_getReg32(unsigned long reg);
extern void extern void
aarch64_set32r(unsigned long reg, unsigned int value); AArch64_setReg32(unsigned long reg, unsigned int value);
extern void extern void
aarch64_delay(unsigned long cycles); AArch64_idle(unsigned long cycles);
extern void extern void
aarch64_irq_enable(void); AArch64_enableIRQ(void);
extern void extern void
aarch64_irq_disable(void); AArch64_disableIRQ(void);
extern void
AArch64_memzero(void *addr, unsigned long size);
#endif /* !AARCH64_H */ #endif /* !AARCH64_H */

View File

@ -1,65 +0,0 @@
/******************************************************************************
*
* Copyright (c) 2017-2019 by Löwenware Ltd
* Please, refer LICENSE file for legal information
*
******************************************************************************/
/**
* @file main.c
* @author Ilja Kartašov <ik@lowenware.com>
* @brief
*
* @see https://lowenware.com/
*/
#include <core/log.h>
#include <core/arch.h>
#include <core/irq.h>
#include <core/timer.h>
void
k_main(void);
void
k_main(void)
{
k_log_init();
k_logs("Starting Lowe OS (EL");
k_logi(aarch64_get_el(), 10);
k_logs(")\r\n");
if (k_arch_init())
goto panic;
k_timer_init();
k_irq_enable_controller();
k_irq_enable();
goto ok;
/*
k_logs("\tclock");
if (k_clock_init())
goto panic;
k_logs(" - ok\n\tscheduler");
if (k_scheduler_init())
goto panic;
k_logs(" - ok\n");
k_scheduler_run();
*/
panic:
k_logs(" - ERROR\n");
ok:
for (;;) {
__asm__("WFE");
}
}

View File

@ -18,6 +18,17 @@
#define PERIPHERAL_BASE 0x3F000000 #define PERIPHERAL_BASE 0x3F000000
/* Reserve 4 MB for the Kernel and its stack */
#define MEMORY_LOW (4 * 1024 * 1024)
#define MEMORY_HIGH PERIPHERAL_BASE
#define MEMORY_SIZE (MEMORY_HIGH - MEMORY_LOW)
#define MEMORY_PAGE_SIZE (4 * 1024)
#define MEMORY_PAGE_COUNT (MEMORY_SIZE / MEMORY_PAGE_SIZE)
/* GPIO */ /* GPIO */
#define GPFSEL1 (PERIPHERAL_BASE + 0x00200004) #define GPFSEL1 (PERIPHERAL_BASE + 0x00200004)
#define GPSET0 (PERIPHERAL_BASE + 0x0020001C) #define GPSET0 (PERIPHERAL_BASE + 0x0020001C)

View File

@ -28,19 +28,19 @@
#if UART_DEFAULT == UART_MINI #if UART_DEFAULT == UART_MINI
#define uart_init(...) uart_mini_init(__VA_ARGS__) #define UART_init(...) UARTMini_init(__VA_ARGS__)
#define uart_read(...) uart_mini_read(__VA_ARGS__) #define UART_get(...) UARTMini_get(__VA_ARGS__)
#define uart_write(...) uart_mini_write(__VA_ARGS__) #define UART_put(...) UARTMini_put(__VA_ARGS__)
#elif UART_DEFAULT == UART_QEMU #elif UART_DEFAULT == UART_QEMU
#define uart_init(...) #define UART_init(...)
#define uart_read(...) #define UART_get(...)
#define uart_write(...) uart_qemu_write(__VA_ARGS__) #define UART_put(...) UARTQEMU_put(__VA_ARGS__)
#else #else
#warning "Unsupported default UART" #warning "Unsupported UART"
#endif #endif

View File

@ -6,7 +6,7 @@
******************************************************************************/ ******************************************************************************/
/** /**
* @file uart_mini.c * @file UARTMini.c
* @author Ilja Kartašov <ik@lowenware.com> * @author Ilja Kartašov <ik@lowenware.com>
* @brief * @brief
* *
@ -16,69 +16,69 @@
#include <aarch64/aarch64.h> #include <aarch64/aarch64.h>
#include <aarch64/bcm2837.h> #include <aarch64/bcm2837.h>
#include "uart_mini.h" #include "UARTMini.h"
int int
uart_mini_init(void) UARTMini_init(void)
{ {
unsigned int sel; unsigned int sel;
/* Enable UART Mini and its registers*/ /* Enable UART Mini and its registers*/
aarch64_set32r(AUX_ENABLES, 1); AArch64_setReg32(AUX_ENABLES, 1);
/* Disable TX and RX interrupts */ /* Disable TX and RX interrupts */
aarch64_set32r(AUX_MU_IER_REG, 0); AArch64_setReg32(AUX_MU_IER_REG, 0);
/* Disable auto flow control, TX and RX */ /* Disable auto flow control, TX and RX */
aarch64_set32r(AUX_MU_CNTL_REG, 0); AArch64_setReg32(AUX_MU_CNTL_REG, 0);
/* Set 8bit mode */ /* Set 8bit mode */
aarch64_set32r(AUX_MU_LCR_REG, 3); AArch64_setReg32(AUX_MU_LCR_REG, 3);
/* Set RTS line HIGH */ /* Set RTS line HIGH */
aarch64_set32r(AUX_MU_MCR_REG, 0); AArch64_setReg32(AUX_MU_MCR_REG, 0);
/* Set baud rate 115200 */ /* Set baud rate 115200 */
aarch64_set32r(AUX_MU_IER_REG, 0); AArch64_setReg32(AUX_MU_IER_REG, 0);
aarch64_set32r(AUX_MU_IIR_REG, 0xC6); AArch64_setReg32(AUX_MU_IIR_REG, 0xC6);
aarch64_set32r(AUX_MU_BAUD_REG, 270); AArch64_setReg32(AUX_MU_BAUD_REG, 270);
sel = aarch64_get32r(GPFSEL1); sel = AArch64_getReg32(GPFSEL1);
/* clean and set ALT5 for GPIO14 */ /* clean and set ALT5 for GPIO14 */
sel &= ~(7 << 12); sel &= ~(7 << 12);
sel |= (2 << 12); sel |= (2 << 12);
/* clean and set ALT5 for GPIO15 */ /* clean and set ALT5 for GPIO15 */
sel &= ~(7 << 15); sel &= ~(7 << 15);
sel |= (2 << 15); sel |= (2 << 15);
aarch64_set32r(GPFSEL1, sel); AArch64_setReg32(GPFSEL1, sel);
aarch64_set32r(GPPUD, 0); AArch64_setReg32(GPPUD, 0);
aarch64_delay(150); AArch64_delay(150);
aarch64_set32r(GPPUDCLK0, (1 << 14) | (1 << 15)); AArch64_setReg32(GPPUDCLK0, (1 << 14) | (1 << 15));
aarch64_delay(150); AArch64_delay(150);
aarch64_set32r(GPPUDCLK0, 0); AArch64_setReg32(GPPUDCLK0, 0);
/* Enable TX and RX */ /* Enable TX and RX */
aarch64_set32r(AUX_MU_CNTL_REG, 3); AArch64_setReg32(AUX_MU_CNTL_REG, 3);
return 0; return 0;
} }
int int
uart_mini_write(char c) UARTMini_put(char c)
{ {
while (1) { while (1) {
if (aarch64_get32r(AUX_MU_LSR_REG) & 0x20) if (AArch64_getReg32(AUX_MU_LSR_REG) & 0x20)
break; break;
} }
aarch64_set32r(AUX_MU_IO_REG, c); AArch64_setReg32(AUX_MU_IO_REG, c);
return 0; return 0;
} }
int int
uart_mini_read(char *pc) UARTMini_get(char *pc)
{ {
while (1) { while (1) {
if (aarch64_get32r(AUX_MU_LSR_REG) & 0x01) if (AArch64_getReg32(AUX_MU_LSR_REG) & 0x01)
break; break;
} }
*pc = aarch64_get32r(AUX_MU_IO_REG) & 0xFF; *pc = AArch64_getReg32(AUX_MU_IO_REG) & 0xFF;
return 0; return 0;
} }

View File

@ -6,7 +6,7 @@
******************************************************************************/ ******************************************************************************/
/** /**
* @file uart_mini.h * @file UARTMini.h
* @author Ilja Kartašov <ik@lowenware.com> * @author Ilja Kartašov <ik@lowenware.com>
* @brief * @brief
* *
@ -17,12 +17,12 @@
#define UART_MINI_H_B0DFA3CF_5B4F_4EB0_B393_391C0069A04F #define UART_MINI_H_B0DFA3CF_5B4F_4EB0_B393_391C0069A04F
int int
uart_mini_init(void); UARTMini_init(void);
int int
uart_mini_write(char c); UARTMini_put(char c);
int int
uart_mini_read(char *pc); UARTMini_get(char *pc);
#endif /* !UART_MINI_H */ #endif /* !UART_MINI_H */

View File

@ -15,16 +15,14 @@
#include "uart_qemu.h" #include "uart_qemu.h"
#define UART_BASE 0x09000000; #define UARTQEMU_BASE 0x09000000;
volatile unsigned int *UART0 = (unsigned int *)UART_BASE; volatile unsigned int *UART0 = (unsigned int *)UARTQEMU_BASE;
int int
uart_qemu_write(unsigned char c) UARTQEMU_put(unsigned char c)
{ {
*UART0 = (unsigned int) c; *UART0 = (unsigned int) c;
return 0; return 0;
} }

View File

@ -17,6 +17,6 @@
#define UART_QEMU_H_EDB39A0E_9BED_4A47_91CD_E804A9B4E8ED #define UART_QEMU_H_EDB39A0E_9BED_4A47_91CD_E804A9B4E8ED
int int
uart_qemu_write(unsigned char c); UARTQEMU_put(unsigned char c);
#endif /* !UART_QEMU_H */ #endif /* !UART_QEMU_H */

View File

@ -16,6 +16,7 @@
#include <aarch64/bcm2837.h> #include <aarch64/bcm2837.h>
#include "timer.h" #include "timer.h"
#include "log.h" #include "log.h"
#include "task.h"
#include "irq.h" #include "irq.h"
static const char *m_types[] = { static const char *m_types[] = {
@ -37,35 +38,45 @@ static const char *m_types[] = {
"EL0_32_ERROR" "EL0_32_ERROR"
}; };
void
k_irq_enable_controller() static unsigned long
IRQ_onTimerInterrupt(void)
{ {
aarch64_set32r(ENABLE_IRQS_1, SYSTEM_TIMER_IRQ_1); Timer_incFromISR();
return Task_scheduleFromISR();
} }
void void
k_irq_handler(void) IRQ_init()
{ {
unsigned int irq = aarch64_get32r(IRQ_PENDING_1); AArch64_setReg32(ENABLE_IRQS_1, SYSTEM_TIMER_IRQ_1);
}
unsigned long
IRQ_onInterrupt(void)
{
unsigned int irq = AArch64_getReg32(IRQ_PENDING_1);
switch(irq) { switch(irq) {
case SYSTEM_TIMER_IRQ_1: case SYSTEM_TIMER_IRQ_1:
k_timer_irq_handler(); return IRQ_onTimerInterrupt();
break;
default: default:
k_logs("Unhandled irq: "); Log_putS("Unhandled irq: ");
k_logu(irq, 16); Log_putU(irq, 16);
k_logs("\n"); Log_putS("\n");
} }
return 0; /* do not change stack pointer */
} }
void void
k_irq_fallback(int type, unsigned long esr, unsigned long address) IRQ_fallback(int type, unsigned long esr, unsigned long address)
{ {
k_logs(m_types[type]); Log_putS(m_types[type]);
k_logs(" -> ESR: "); Log_putS(" -> ESR: ");
k_logu(esr, 16); Log_putU(esr, 16);
k_logs(", address: "); Log_putS(", address: ");
k_logu(address, 16); Log_putU(address, 16);
k_logs("\r\n"); Log_putS("\r\n");
} }

View File

@ -19,16 +19,16 @@
#include <aarch64/aarch64.h> #include <aarch64/aarch64.h>
void void
k_irq_enable_controller(void); IRQ_init(void);
unsigned long
IRQ_onInterrupt(void);
void void
k_irq_handler(void); IRQ_fallback(int type, unsigned long esr, unsigned long address);
void #define IRQ_enable(...) AArch64_enableIRQ(__VA_ARGS__)
k_irq_fallback(int type, unsigned long esr, unsigned long address);
#define k_irq_enable(...) aarch64_irq_enable(__VA_ARGS__) #define IRQ_disable(...) AArch64_disableIRQ(__VA_ARGS__)
#define k_irq_disable(...) aarch64_irq_disable(__VA_ARGS__)
#endif /* !IRQ_H */ #endif /* !IRQ_H */

42
kernel/leos/leos.c Normal file
View File

@ -0,0 +1,42 @@
/******************************************************************************
*
* Copyright (c) 2017-2019 by Löwenware Ltd
* Please, refer LICENSE file for legal information
*
******************************************************************************/
/**
* @file main.c
* @author Ilja Kartašov <ik@lowenware.com>
* @brief
*
* @see https://lowenware.com/
*/
#include <leos/log.h>
#include <leos/arch.h>
#include <leos/irq.h>
#include <leos/timer.h>
#include <leos/leos.h>
void
Leos_run(void)
{
Log_init();
Log_putS("Starting Lowe OS (EL");
Log_putI(AArch64_getEL(), 10);
Log_putS(")\r\n");
Arch_init();
Timer_init();
IRQ_init();
IRQ_enable();
for (;;) {
__asm__("WFE");
}
}

22
kernel/leos/leos.h Normal file
View File

@ -0,0 +1,22 @@
/******************************************************************************
*
* Copyright (c) 2017-2020 by Löwenware Ltd
* Please, refer LICENSE file for legal information
*
******************************************************************************/
/**
* @file leos.h
* @author Ilja Kartašov <ik@lowenware.com>
* @brief
*
* @see https://lowenware.com/
*/
#ifndef LEOS_H_7087F58B_BDEB_433B_A013_5B5F854922AF
#define LEOS_H_7087F58B_BDEB_433B_A013_5B5F854922AF
void
Leos_run(void);
#endif /* !LEOS_H */

View File

@ -17,31 +17,31 @@
#include "log.h" #include "log.h"
void void
k_log_init(void) Log_init(void)
{ {
uart_init(); UART_init();
} }
Ki32 int
k_logs(const Ki8 *string) Log_putS(const char *string)
{ {
Ki8 c; char c;
const Ki8 *p = string; const char *p = string;
while((c = *p) != 0) { while((c = *p) != 0) {
if (uart_write(c)) if (UART_send(c))
return -1; return -1;
p++; p++;
} }
return (Ki32)(p - string); return (int)(p - string);
} }
Ki32 int
k_logi(Ki64 value, Ku8 base) Log_putI(int64_t value, uint8_t base)
{ {
Ki32 result; int result;
if (value < 0) { if (value < 0) {
if (uart_write('-')) if (UART_send('-'))
return -1; return -1;
value = -value; value = -value;
result = 1; result = 1;
@ -52,21 +52,22 @@ k_logi(Ki64 value, Ku8 base)
return (result) ? result : -1; return (result) ? result : -1;
} }
Ki32 int
k_logu(Ku64 value, Ku8 base) Log_putU(uint64_t value, uint8_t base)
{ {
Ki32 i = 0, result; int i = 0, result;
Ku8 buffer[64]; char buffer[64];
if (!value) { if (!value) {
return (uart_write('0')) ? -1 : 1; return (UART_send('0')) ? -1 : 1;
} }
do { do {
uint64_t r;
if (!(i < (sizeof(buffer) / sizeof(buffer[0])))) if (!(i < (sizeof(buffer) / sizeof(buffer[0]))))
return -1; return -1;
Ku64 r = value % base; r = value % base;
buffer[i++] = (r < 0x0A) ? '0' + r : 'A' + r - 0x0A; buffer[i++] = (r < 0x0A) ? '0' + r : 'A' + r - 0x0A;
value /= base; value /= base;
} while (value); } while (value);
@ -74,7 +75,7 @@ k_logu(Ku64 value, Ku8 base)
result = i; result = i;
while (i--) { while (i--) {
if (uart_write(buffer[i])) if (UART_send(buffer[i]))
return -1; return -1;
} }
return result; return result;

View File

@ -19,15 +19,15 @@
#include <core/types.h> #include <core/types.h>
void void
k_log_init(void); Log_init(void);
Ki32 int
k_logs(const Ki8 *string); Log_putS(const char *string);
Ki32 int
k_logi(Ki64 value, Ku8 base); Log_putI(int64_t value, uint8_t base);
Ki32 int
k_logu(Ku64 value, Ku8 base); Log_putU(uint64_t value, uint8_t base);
#endif /* !LOG_H */ #endif /* !LOG_H */

54
kernel/leos/memory.c Normal file
View File

@ -0,0 +1,54 @@
/******************************************************************************
*
* Copyright (c) 2017-2020 by Löwenware Ltd
* Please, refer LICENSE file for legal information
*
******************************************************************************/
/**
unsigned
* @file memory.c
* @author Ilja Kartašov <ik@lowenware.com>
* @brief
*
* @see https://lowenware.com/
*/
#include <stdlib.h>
#include <aarch64/bcm2837.h>
#include "memory.h"
static unsigned long m_map[MEMORY_PAGE_COUNT / sizeof(unsigned long) / 8] = {0,};
static int m_ix = 0;
void *
Memory_getPage(void)
{
int i, j;
unsigned long map;
for (i = m_ix; i < sizeof(m_map) / sizeof(m_map[0]); i++) {
map = m_map[i];
for (j = 0; j < 8 * sizeof(map); j++) {
if (!(map & (1 << j))) {
m_map[i] |= (1 << j);
return (void *) ((i * sizeof(map) * 8 + j) * MEMORY_PAGE_SIZE);
}
}
m_ix = i;
}
return NULL;
}
void
Memory_freePage(void *p_addr)
{
int i, j, c;
c = ((unsigned long) p_addr) / MEMORY_PAGE_SIZE;
i = c / sizeof(m_map[0]);
j = c % sizeof(m_map[0]);
m_map[i] &= ~(1 << j);
}

26
kernel/leos/memory.h Normal file
View File

@ -0,0 +1,26 @@
/******************************************************************************
*
* Copyright (c) 2017-2020 by Löwenware Ltd
* Please, refer LICENSE file for legal information
*
******************************************************************************/
/**
* @file memory.h
* @author Ilja Kartašov <ik@lowenware.com>
* @brief
*
* @see https://lowenware.com/
*/
#ifndef MEMORY_H_C583E24E_55B0_49EF_99C9_5A36B04468AC
#define MEMORY_H_C583E24E_55B0_49EF_99C9_5A36B04468AC
void *
Memory_getPage(void);
void
Memory_freePage(void *p_addr);
#endif /* !MEMORY_H */

92
kernel/leos/scheduler.c Normal file
View File

@ -0,0 +1,92 @@
/******************************************************************************
*
* Copyright (c) 2017-2020 by Löwenware Ltd
* Please, refer LICENSE file for legal information
*
******************************************************************************/
/**
* @file scheduler.c
* @author Ilja Kartašov <ik@lowenware.com>
* @brief
*
* @see https://lowenware.com/
*/
#include "scheduler.h"
static struct KTask *m_first = NULL, *m_last, *m_current = NULL;
static KPid m_pid = 0;
static void
_disable_preempt(void)
{
m_current->preempt++;
}
static void
_enable_preempt(void)
{
m_current->preempt--;
}
static void
_switch(void)
{
struct KTask *i, *next;
long p = 0;
_disable_preempt();
for (;;) {
/* check urgent tasks */
for (i = m_first; i != NULL; i = i->next) {
if (!i->state && i->counter > p) {
p = i->counter;
next = i;
}
i = i->next;
}
if (p) {
break;
}
i = m_first;
for (i = m_first; i != NULL; i = i->next) {
i->counter = i->priority;
}
}
aarch64_switch(m_current, next);
_enable_preempt();
}
void
scheduler_init(void)
{
}
KPid
scheduler_add(struct KTask *task)
{
KPid result = ++m_pid;
task->pid = result;
task->prev = m_last;
m_last->next = task;
return result;
}
void
scheduler_switch(void)
{
}
void
scheduler_switch_from_isr(void)
{
}

38
kernel/leos/scheduler.h Normal file
View File

@ -0,0 +1,38 @@
/******************************************************************************
*
* Copyright (c) 2017-2019 by Löwenware Ltd
* Please, refer LICENSE file for legal information
*
******************************************************************************/
/**
* @file scheduler.h
* @author Ilja Kartašov <ik@lowenware.com>
* @brief
*
* @see https://lowenware.com/
*/
#ifndef SCHEDULER_H_AE39DBC8_E643_4857_B319_9732123728A4
#define SCHEDULER_H_AE39DBC8_E643_4857_B319_9732123728A4
void
scheduler_init(void);
void
scheduler_run(void);
void
scheduler_switch(void);
KPid
scheduler_add(struct KTask *task);
KRetCode
scheduler_remove(struct KTask *task);
KRetCode
scheduler_remove_pid(KPid pid);
#endif /* !SCHEDULER_H */

View File

@ -18,20 +18,19 @@
#include <core/types.h> #include <core/types.h>
typedef Ku32 KTaskId; typedef void (*TaskCallback)(void *p_ctx);
typedef void (*KTaskCallback)(void *p_ctx);
struct k_task { struct Task {
KByte name[K_CONFIG_TASK_MAX_NAME_LEN + 1]; char name[CONFIG_TASK_MAX_NAME_LEN + 1];
KTaskCallback callback; TaskCallback callback;
Ku32 *stack; uint64_t *stack;
Ku32 stack_size; uint32_t stack_size;
Ku32 priority; uint32_t priority;
}; };
KTaskId PID
k_task_create(struct k_task *p_task, KTaskCallback callback, Ku32 *stack Task_create(struct Task *pTask, TaskCallback callback, uint64_t *stack
, Ku32 stack_size); , uint32_t stack_size);
#endif /* !TASK_H */ #endif /* !TASK_H */

View File

@ -16,14 +16,10 @@
#ifndef TYPES_H_BC3DA9C0_C9EE_4853_B5F5_EAA4B801664C #ifndef TYPES_H_BC3DA9C0_C9EE_4853_B5F5_EAA4B801664C
#define TYPES_H_BC3DA9C0_C9EE_4853_B5F5_EAA4B801664C #define TYPES_H_BC3DA9C0_C9EE_4853_B5F5_EAA4B801664C
typedef int KRetCode; #include <stdbool.h>
#include <stdint.h>
typedef int Ki32; typedef int RetCode;
typedef unsigned int Ku32; typedef unsigned int PID;
typedef long long Ki64;
typedef unsigned long long Ku64;
typedef char Ki8;
typedef unsigned char Ku8;
typedef char KByte;
#endif /* !TYPES_H */ #endif /* !TYPES_H */