uniLoader: Mass rework

arch: aarch64: Load addresses via page + offset
arch: aarch64: Align the TEXT region
drivers: Introduce an empty framework
board: Rework to be PIC

Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
This commit is contained in:
Ivaylo Ivanov 2024-10-08 21:17:10 +03:00
parent b301e51432
commit 81d26edaa3
27 changed files with 534 additions and 248 deletions

4
.gitignore vendored
View File

@ -14,3 +14,7 @@ lib/*.a*
include/config/auto.conf
include/generated/autoconf.h
include/config
boot.img
blob/Image
blob/dtb
drivers/*.a

View File

@ -195,6 +195,7 @@ KBUILD_CPPFLAGS := -D__KERNEL__
KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common \
-fno-stack-protector \
-Werror-implicit-function-declaration \
-Wno-format-security \
-fno-delete-null-pointer-checks \
@ -346,14 +347,21 @@ main-y := arch/$(ARCH)/start.o \
# Object directories
objs-y := main
objs-y += arch
# Libraries
libs-y := soc
libs-y += board
libs-y += lib
libs-y += drivers
# Include these in the build process as we
uniLoader-dirs := $(objs-y) $(libs-y)
uniLoader-objs := $(patsubst %,%/built-in.o, $(objs-y))
uniLoader-mains := $(objs-y)/*.o
uniLoader-libs := $(patsubst %,%/lib.a, $(libs-y))
uniLoader-mains := $(objs-y)/*.o
uniLoader-all := $(uniLoader-objs) $(uniLoader-libs)
# Do modpost on a prelinked vmlinux. The finally linked vmlinux has

View File

@ -16,7 +16,7 @@ SECTIONS
arch/aarch64/start.o
}
.text : {
.text ALIGN(4096) : {
*(.text)
}

View File

@ -7,15 +7,20 @@
.section .text
ENTRY _start
/* Set up the base address for the stack */
adr x0, _stack_end
adrp x0, _stack_end /* Load page of the _stack_end symbol */
add x0, x0, #:lo12:_stack_end /* Add the offset within the page */
/* Set up the stack pointer (SP) */
mov sp, x0
/* Fall through */
adr x0, dtb
adr x1, kernel
b main
adrp x0, dtb /* Load page of dtb */
add x0, x0, #:lo12:dtb /* Add offset within the page */
adrp x1, kernel /* Load page of kernel */
add x1, x1, #:lo12:kernel /* Add offset within the page */
bl main
ENDPROC _start
ENTRY load_kernel
br x4

View File

@ -101,16 +101,16 @@ menu "Device Specific Addresses"
hex "Framebuffer Base Address (for SimpleFB)"
depends on SIMPLE_FB
default 0x83e900000 if APPLE_N61AP
default 0x0F1000000 if SAMSUNG_C1S
default 0x0f1000000 if SAMSUNG_C1S
default 0x0e2a00000 if SAMSUNG_NOBLELTE
default 0x0ec000000 if SAMSUNG_JACKPOTLTE
default 0x0e2a00000 if SAMSUNG_ZEROFLTE
default 0x0cc000000 if SAMSUNG_DREAMLTE
default 0x0cc000000 if SAMSUNG_STARLTE
default 0x0F1000000 if SAMSUNG_X1S
default 0x0f1000000 if SAMSUNG_X1S
default 0x067000000 if SAMSUNG_J4LTE
default 0x08e000000 if SAMSUNG_J5LTE
default 0x0CA000000 if SAMSUNG_GTA4XL
default 0x0ca000000 if SAMSUNG_GTA4XL
config FRAMEBUFFER_WIDTH
int "Framebuffer Width (for SimpleFB)"

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x19050000
#define HW_SW_TRIG_CONTROL 0x70
void init_board_funcs(void *board)
{
/*
* Parsing the struct directly without restructing is
* broken as of Sep 29 2024
*/
struct {
const char *name;
int ops[BOARD_OP_EXIT];
} *board_restruct = board;
board_restruct->name = "C1S";
}
// Early initialization
static void c1s_init(void)
int board_init(void)
{
/* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
}
// Late initialization
static void c1s_late_init(void)
int board_late_init(void)
{
return 0;
}
static void c1s_driver_setup(void)
int board_driver_setup(void)
{
// Register drivers for S5PV210-specific peripherals
// register_driver(&simplefb_driver);
// Add more drivers here as needed
}
struct {
int width;
int height;
int stride;
void *address;
} simplefb_data = {
.width = 1080,
.height = 2400,
.stride = 4,
.address = (void *)0xf1000000
};
// Create the board_data structure for S5PV210
static struct board_data c1s_board = {
.name = "C1S",
.init = c1s_init,
.late_init = c1s_late_init,
.driver_setup = c1s_driver_setup,
};
// Function to retrieve current board data (could be hardcoded or chosen via config)
struct board_data *get_current_board(void) {
return &c1s_board; // Return the correct board based on runtime config
REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
return 0;
}

View File

@ -3,39 +3,54 @@
* Copyright (c) 2022, Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
*/
#include <board.h>
#include <drivers/framework.h>
#include <lib/simplefb.h>
#define DECON_F_BASE 0x12860000
#define HW_SW_TRIG_CONTROL 0x70
void init_board_funcs(void *board)
{
/*
* Parsing the struct directly without restructing is
* broken as of Sep 29 2024
*/
struct {
const char *name;
int ops[BOARD_OP_EXIT];
} *board_restruct = board;
board_restruct->name = "DREAMLTE";
}
// Early initialization
static void dreamlte_init(void)
int board_init(void)
{
/* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
}
// Late initialization
static void dreamlte_late_init(void)
int board_late_init(void)
{
return 0;
}
static void dreamlte_driver_setup(void)
int board_driver_setup(void)
{
// Register drivers for S5PV210-specific peripherals
// register_driver(&simplefb_driver);
// Add more drivers here as needed
}
struct {
int width;
int height;
int stride;
void *address;
} simplefb_data = {
.width = 1440,
.height = 2960,
.stride = 4,
.address = (void *)0xcc000000
};
// Create the board_data structure for S5PV210
static struct board_data dreamlte_board = {
.name = "DREAMLTE",
.init = dreamlte_init,
.late_init = dreamlte_late_init,
.driver_setup = dreamlte_driver_setup,
};
// Function to retrieve current board data (could be hardcoded or chosen via config)
struct board_data *get_current_board(void) {
return &dreamlte_board; // Return the correct board based on runtime config
REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
return 0;
}

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x148b0000
#define HW_SW_TRIG_CONTROL 0x70
void init_board_funcs(void *board)
{
/*
* Parsing the struct directly without restructing is
* broken as of Sep 29 2024
*/
struct {
const char *name;
int ops[BOARD_OP_EXIT];
} *board_restruct = board;
board_restruct->name = "GTA4XL";
}
// Early initialization
static void gta4xl_init(void)
int board_init(void)
{
/* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
}
// Late initialization
static void gta4xl_late_init(void)
int board_late_init(void)
{
return 0;
}
static void gta4xl_driver_setup(void)
int board_driver_setup(void)
{
// Register drivers for S5PV210-specific peripherals
// register_driver(&simplefb_driver);
// Add more drivers here as needed
}
struct {
int width;
int height;
int stride;
void *address;
} simplefb_data = {
.width = 1200,
.height = 2000,
.stride = 4,
.address = (void *)0xca000000
};
// Create the board_data structure for S5PV210
static struct board_data gta4xl_board = {
.name = "GTA4XL",
.init = gta4xl_init,
.late_init = gta4xl_late_init,
.driver_setup = gta4xl_driver_setup,
};
// Function to retrieve current board data
struct board_data *get_current_board(void) {
return &gta4xl_board; // Return the correct board based on runtime config
REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
return 0;
}

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x14830000
#define HW_SW_TRIG_CONTROL 0x70
void init_board_funcs(void *board)
{
/*
* Parsing the struct directly without restructing is
* broken as of Sep 29 2024
*/
struct {
const char *name;
int ops[BOARD_OP_EXIT];
} *board_restruct = board;
board_restruct->name = "J4LTE";
}
// Early initialization
static void j4lte_init(void)
int board_init(void)
{
/* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
}
// Late initialization
static void j4lte_late_init(void)
int board_late_init(void)
{
return 0;
}
static void j4lte_driver_setup(void)
int board_driver_setup(void)
{
// Register drivers for S5PV210-specific peripherals
// register_driver(&simplefb_driver);
// Add more drivers here as needed
}
struct {
int width;
int height;
int stride;
void *address;
} simplefb_data = {
.width = 720,
.height = 1280,
.stride = 4,
.address = (void *)0x67000000
};
// Create the board_data structure for S5PV210
static struct board_data j4lte_board = {
.name = "J4LTE",
.init = j4lte_init,
.late_init = j4lte_late_init,
.driver_setup = j4lte_driver_setup,
};
// Function to retrieve current board data
struct board_data *get_current_board(void) {
return &j4lte_board; // Return the correct board based on runtime config
REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
return 0;
}

View File

@ -5,6 +5,8 @@
#include <board.h>
#include <main.h>
#include <drivers/framework.h>
#include <lib/simplefb.h>
#define PIPE_SSPP_SRC_FORMAT 0x30
#define PIPE_SSPP_SRC_UNPACK_PATTERN 0x34
@ -14,37 +16,51 @@
#define MDP_CTL_0_BASE 0x1A02000
#define MDP_CTL_FLUSH 0x18
static void j5lte_init(void)
void init_board_funcs(void *board)
{
/*
* Parsing the struct directly without restructing is
* broken as of Sep 29 2024
*/
struct {
const char *name;
int ops[BOARD_OP_EXIT];
} *board_restruct = board;
board_restruct->name = "J5LTE";
}
int board_init(void)
{
/* TODO: Doesn't really work :P */
writel(0x000236FF, PIPE_BASE + PIPE_SSPP_SRC_FORMAT);
writel(0x03020001, PIPE_BASE + PIPE_SSPP_SRC_UNPACK_PATTERN);
writel((720 * 4), MDP_CTL_0_BASE + MDP_CTL_FLUSH);
writel((1 << (0)), PIPE_BASE + PIPE_SSPP_SRC_YSTRIDE);
return 0;
}
// Late initialization
static void j5lte_late_init(void)
int board_late_init(void)
{
return 0;
}
static void j5lte_driver_setup(void)
int board_driver_setup(void)
{
// Register drivers for S5PV210-specific peripherals
// register_driver(&simplefb_driver);
// Add more drivers here as needed
}
struct {
int width;
int height;
int stride;
void *address;
} simplefb_data = {
.width = 720,
.height = 1280,
.stride = 3,
.address = (void *)0x8e000000
};
// Create the board_data structure for S5PV210
static struct board_data j5lte_board = {
.name = "J5LTE",
.init = j5lte_init,
.late_init = j5lte_late_init,
.driver_setup = j5lte_driver_setup,
};
// Function to retrieve current board data
struct board_data *get_current_board(void) {
return &j5lte_board; // Return the correct board based on runtime config
REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
return 0;
}

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x14860000
#define HW_SW_TRIG_CONTROL 0x70
void init_board_funcs(void *board)
{
/*
* Parsing the struct directly without restructing is
* broken as of Sep 29 2024
*/
struct {
const char *name;
int ops[BOARD_OP_EXIT];
} *board_restruct = board;
board_restruct->name = "JACKPOTLTE";
}
// Early initialization
static void jackpotlte_init(void)
int board_init(void)
{
/* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
}
// Late initialization
static void jackpotlte_late_init(void)
int board_late_init(void)
{
return 0;
}
static void jackpotlte_driver_setup(void)
int board_driver_setup(void)
{
// Register drivers for S5PV210-specific peripherals
// register_driver(&simplefb_driver);
// Add more drivers here as needed
}
struct {
int width;
int height;
int stride;
void *address;
} simplefb_data = {
.width = 1080,
.height = 2200,
.stride = 4,
.address = (void *)0xec000000
};
// Create the board_data structure for S5PV210
static struct board_data jackpotlte_board = {
.name = "JACKPOTLTE",
.init = jackpotlte_init,
.late_init = jackpotlte_late_init,
.driver_setup = jackpotlte_driver_setup,
};
// Function to retrieve current board data
struct board_data *get_current_board(void) {
return &jackpotlte_board; // Return the correct board based on runtime config
REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
return 0;
}

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x13930000
#define HW_SW_TRIG_CONTROL 0x6b0
void init_board_funcs(void *board)
{
/*
* Parsing the struct directly without restructing is
* broken as of Sep 29 2024
*/
struct {
const char *name;
int ops[BOARD_OP_EXIT];
} *board_restruct = board;
board_restruct->name = "NOBLELTE";
}
// Early initialization
static void noblelte_init(void)
int board_init(void)
{
/* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x2058;
return 0;
}
// Late initialization
static void noblelte_late_init(void)
int board_late_init(void)
{
return 0;
}
static void noblelte_driver_setup(void)
int board_driver_setup(void)
{
// Register drivers for S5PV210-specific peripherals
// register_driver(&simplefb_driver);
// Add more drivers here as needed
}
struct {
int width;
int height;
int stride;
void *address;
} simplefb_data = {
.width = 1440,
.height = 2560,
.stride = 4,
.address = (void *)0xe2a00000
};
// Create the board_data structure for S5PV210
static struct board_data noblelte_board = {
.name = "NOBLELTE",
.init = noblelte_init,
.late_init = noblelte_late_init,
.driver_setup = noblelte_driver_setup,
};
// Function to retrieve current board data
struct board_data *get_current_board(void) {
return &noblelte_board; // Return the correct board based on runtime config
REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
return 0;
}

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x16030000
#define HW_SW_TRIG_CONTROL 0x70
void init_board_funcs(void *board)
{
/*
* Parsing the struct directly without restructing is
* broken as of Sep 29 2024
*/
struct {
const char *name;
int ops[BOARD_OP_EXIT];
} *board_restruct = board;
board_restruct->name = "STARLTE";
}
// Early initialization
static void starlte_init(void)
int board_init(void)
{
/* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
}
// Late initialization
static void starlte_late_init(void)
int board_late_init(void)
{
return 0;
}
static void starlte_driver_setup(void)
int board_driver_setup(void)
{
// Register drivers for S5PV210-specific peripherals
// register_driver(&simplefb_driver);
// Add more drivers here as needed
}
struct {
int width;
int height;
int stride;
void *address;
} simplefb_data = {
.width = 1440,
.height = 2960,
.stride = 4,
.address = (void *)0xcc000000
};
// Create the board_data structure for S5PV210
static struct board_data starlte_board = {
.name = "STARLTE",
.init = starlte_init,
.late_init = starlte_late_init,
.driver_setup = starlte_driver_setup,
};
// Function to retrieve current board data
struct board_data *get_current_board(void) {
return &starlte_board; // Return the correct board based on runtime config
REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
return 0;
}

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x19050000
#define HW_SW_TRIG_CONTROL 0x70
void init_board_funcs(void *board)
{
/*
* Parsing the struct directly without restructing is
* broken as of Sep 29 2024
*/
struct {
const char *name;
int ops[BOARD_OP_EXIT];
} *board_restruct = board;
board_restruct->name = "X1S";
}
// Early initialization
static void x1s_init(void)
int board_init(void)
{
/* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
}
// Late initialization
static void x1s_late_init(void)
int board_late_init(void)
{
return 0;
}
static void x1s_driver_setup(void)
int board_driver_setup(void)
{
// Register drivers for S5PV210-specific peripherals
// register_driver(&simplefb_driver);
// Add more drivers here as needed
}
struct {
int width;
int height;
int stride;
void *address;
} simplefb_data = {
.width = 1440,
.height = 3200,
.stride = 4,
.address = (void *)0xf1000000
};
// Create the board_data structure for S5PV210
static struct board_data x1s_board = {
.name = "X1S",
.init = x1s_init,
.late_init = x1s_late_init,
.driver_setup = x1s_driver_setup,
};
// Function to retrieve current board data
struct board_data *get_current_board(void) {
return &x1s_board; // Return the correct board based on runtime config
REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
return 0;
}

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x13930000
#define HW_SW_TRIG_CONTROL 0x6b0
void init_board_funcs(void *board)
{
/*
* Parsing the struct directly without restructing is
* broken as of Sep 29 2024
*/
struct {
const char *name;
int ops[BOARD_OP_EXIT];
} *board_restruct = board;
board_restruct->name = "ZEROFLTE";
}
// Early initialization
static void zeroflte_init(void)
int board_init(void)
{
/* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x2058;
return 0;
}
// Late initialization
static void zeroflte_late_init(void)
int board_late_init(void)
{
return 0;
}
static void zeroflte_driver_setup(void)
int board_driver_setup(void)
{
// Register drivers for S5PV210-specific peripherals
// register_driver(&simplefb_driver);
// Add more drivers here as needed
}
struct {
int width;
int height;
int stride;
void *address;
} simplefb_data = {
.width = 1440,
.height = 2560,
.stride = 4,
.address = (void *)0xe2a00000
};
// Create the board_data structure for S5PV210
static struct board_data zeroflte_board = {
.name = "ZEROFLTE",
.init = zeroflte_init,
.late_init = zeroflte_late_init,
.driver_setup = zeroflte_driver_setup,
};
// Function to retrieve current board data
struct board_data *get_current_board(void) {
return &zeroflte_board; // Return the correct board based on runtime config
REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
return 0;
}

2
drivers/Makefile Normal file
View File

@ -0,0 +1,2 @@
# the drivers registration framework
lib-y += framework.o

13
drivers/framework.c Normal file
View File

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Drivers registration framework
* Copyright (c) 2024, Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
*/
#include <drivers/framework.h>
#include <stddef.h>
// Max number of drivers that can be registered
#define MAX_DRIVERS 256
#define DRIVER_NAME_LEN 20
// TODO

View File

@ -12,28 +12,46 @@
* Well, well, well. We come back to this style again.
* TODO: Implement libfdt once we have C libs all sorted out.
*
* @name -> board name
* @init -> initialization as soon as we hit C
* @late_init -> late initialization
* @driver_setup -> driver initialization
* BOARD_OP_INIT -> initialization as soon as we hit C
* BOARD_OP_LATE_INIT -> late initialization
* BOARD_OP_DRIVER_SETUP -> drivers setup
* BOARD_OP_EXIT -> the last op, currently unused
*/
enum board_ops {
BOARD_OP_INIT,
BOARD_OP_LATE_INIT,
BOARD_OP_DRIVER_SETUP,
BOARD_OP_EXIT
};
// Hold board data WITHOUT POINTERS
struct board_data {
const char *name;
void (*init)(void);
void (*late_init)(void);
void (*driver_setup)(void);
int ops[BOARD_OP_EXIT];
};
extern struct board_data *get_current_board(void);
extern void init_board_funcs(void *board);
// Declare a weak reference to the board data structure
extern struct board_data __attribute__((weak)) default_board;
extern int board_driver_setup(void);
extern int board_init(void);
extern int board_late_init(void);
struct board_data default_board = {
.name = "DEFAULT",
.init = NULL, // No init function for the default
.late_init = NULL,
.driver_setup = NULL,
};
// Macro definitions for board operations
#define EXECUTE_BOARD_OP(op_id) \
do { \
switch (op_id) { \
case BOARD_OP_INIT: \
board_init(); \
break; \
case BOARD_OP_LATE_INIT: \
board_late_init(); \
break; \
case BOARD_OP_DRIVER_SETUP: \
board_driver_setup(); \
break; \
default: \
break; \
} \
} while (0)
#endif // BOARD_H_

View File

@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Drivers registration framework
* Copyright (c) 2024, Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
*/
#ifndef DRIVERS_H_ /* Include guard */
#define DRIVERS_H_
#include <stddef.h>
#include <string.h>
// Define the type for the probe function pointer
typedef void (*probe_func_t)(void *data);
extern probe_func_t find_driver_probe(const char *name);
// Function registry entry
struct driver_registry_entry {
const char *name; // Driver name
probe_func_t probe; // Function pointer to the probe function
};
#define REGISTER_DRIVER(name, probe_func, data) \
do { \
(probe_func)(data); \
} while (0)
#define PASS_STRUCT(name, probe_func, data) \
do { \
(probe_func)(data); \
} while (0)
#endif // DRIVERS_H_

View File

@ -8,6 +8,18 @@
#ifndef SIMPLEFB_H_ /* Include guard */
#define SIMPLEFB_H_
#include <stdint.h>
extern void simplefb_probe(void *data);
extern struct video *video_info;
struct video {
int width;
int height;
int stride;
void *address;
};
typedef struct _color {
unsigned char r;
unsigned char g;

View File

@ -11,7 +11,6 @@
extern unsigned long kernel_size;
extern void load_kernel(void* dtb, void* x1, void* x2, void* x3, void* kernel);
extern void soc_init(void);
extern void board_init(void);
extern void clean_fb(volatile char *fb, int width, int height, int stride);
extern void printk(char *text);

View File

@ -3,17 +3,9 @@
* Copyright (c) 2022, Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
*/
#include <lib/debug.h>
#include <lib/simplefb.h>
#include <stddef.h>
/* TODO: Import libc */
void writel(unsigned int value, void* address) {
// Cast the address pointer to a 32-bit unsigned integer pointer
volatile unsigned int* ptr = (volatile unsigned int*)address;
// Write the value to the memory location
*ptr = value;
}
void printk(char *text) {
#ifdef CONFIG_SIMPLE_FB
/* IMPORTANT: Limit the linecount */

View File

@ -4,18 +4,23 @@
* Copyright (c) 2022, Markuss Broks <markuss.broks@gmail.com>
* Copyright (c) 2022, Michael Srba <Michael.Srba@seznam.cz>
*/
#include <lib/simplefb.h>
#include <drivers/framework.h>
#include <lib/font.h>
#include <lib/simplefb.h>
#include <string.h>
void clean_fb(volatile char *fb, int width, int height, int stride) {
/* volatile char */
static void clean_fb(void *fb, int width, int height, int stride) {
memset(fb, 0x0, (width * height * stride));
}
/* RGB888 format */
/* Unlike ARGB8888, we explicitly use 3 bytes to represent each pixel, making sure no extra padding byte is added. */
void draw_pixel(volatile char *fb, int x, int y, int width, int stride, color c) {
// RGB888 format
/*
* Unlike ARGB8888, we explicitly use 3 bytes to represent each pixel, making sure
* no extra padding byte is added.
*/
static void draw_pixel(volatile char *fb, int x, int y, int width, int stride, color c)
{
long int location = (x * stride) + (y * width * stride);
#ifdef CONFIG_FRAMEBUFFER_BGRA
*(fb + location) = c.b;
@ -30,22 +35,29 @@ void draw_pixel(volatile char *fb, int x, int y, int width, int stride, color c)
#endif
}
void draw_horizontal_line(volatile char *fb, int x1, int x2, int y, color c, int width, int stride) {
static void draw_horizontal_line(volatile char *fb, int x1, int x2, int y, color c,
int width, int stride)
{
for (int i = x1; i < x2; i++)
draw_pixel(fb, i, y, width, stride, c);
}
void draw_vertical_line(volatile char *fb, int x, int y1, int y2, color c, int width, int stride) {
static void draw_vertical_line(volatile char *fb, int x, int y1, int y2, color c,
int width, int stride)
{
for (int i = y1; i < y2; i++)
draw_pixel(fb, x, i, width, stride, c);
}
void draw_filled_rectangle(volatile char *fb, int x1, int y1, int w, int h, color c, int width, int stride) {
static void draw_filled_rectangle(volatile char *fb, int x1, int y1, int w, int h,
color c, int width, int stride)
{
for (int i = y1; i < (y1 + h); i++)
draw_horizontal_line(fb, x1, (x1 + w), i, c, width, stride);
}
void draw_text(volatile char *fb, char *text, int textX, int textY, int width, int stride) {
void draw_text(volatile char *fb, char *text, int textX, int textY, int width, int stride)
{
// loop through all characters in the text string
int l = strlen(text);
@ -61,8 +73,19 @@ void draw_text(volatile char *fb, char *text, int textX, int textY, int width, i
for (int x = 0; x < FONTW; x++) {
if (((b << x) & 0b10000000) > 0)
draw_pixel(fb, textX + i * FONTW + x, textY + y, width, stride, (color){255, 255, 255});
draw_pixel(fb, textX + i * FONTW + x, textY + y, width,
stride, (color){255, 255, 255});
}
}
}
}
void simplefb_probe(void *data)
{
struct video *fb_info = data;
clean_fb((char*)fb_info->address, fb_info->width, fb_info->height,
fb_info->stride);
/* TODO: Introduce a full drivers framework that allows proper exiting */
}

24
lib/unic/stdint.h Normal file
View File

@ -0,0 +1,24 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright (c) 2024, Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
*/
#ifndef INTTYPES_H /* Include guard */
#define INTTYPES_H
typedef char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#ifdef __x86_64__
typedef unsigned long uint64_t;
typedef long int64_t;
#else
typedef unsigned long long uint64_t;
typedef long long int64_t;
#endif
#endif // INTTYPES_H

View File

@ -207,3 +207,9 @@ long atol(const char *s)
return val;
}
void writel(unsigned int value, void* address)
{
volatile unsigned int* ptr = (volatile unsigned int*)address;
*ptr = value;
}

View File

@ -22,6 +22,7 @@ size_t strnlen(const char *s, size_t n);
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
long atol(const char *s);
void writel(unsigned int value, void* address);
static inline int tolower(int c)
{

View File

@ -7,21 +7,32 @@
#include <main.h>
#include <string.h>
void main(void* dt, void* kernel) {
/*
* Provide an empty board config that has
* to be filled in the board files
* TODO: figure out why having it in
* the board files makes devices reboot.
*/
struct board_data board = {
.name = "default",
.ops = {
[BOARD_OP_INIT] = BOARD_OP_INIT,
[BOARD_OP_LATE_INIT] = BOARD_OP_LATE_INIT,
[BOARD_OP_DRIVER_SETUP] = BOARD_OP_DRIVER_SETUP,
}
};
void main(void* dt, void* kernel)
{
/* Initialize SoC and Board specific peripherals/quirks */
struct board_data *board = get_current_board();
init_board_funcs(&board);
/* TODO: Move into the simpleFB driver once the drivers framework is done */
#ifdef CONFIG_SIMPLE_FB
clean_fb((char*)CONFIG_FRAMEBUFFER_BASE, CONFIG_FRAMEBUFFER_WIDTH, CONFIG_FRAMEBUFFER_HEIGHT, CONFIG_FRAMEBUFFER_STRIDE);
#endif
board->init();
printk("board init() passed!");
EXECUTE_BOARD_OP(board.ops[BOARD_OP_INIT]);
EXECUTE_BOARD_OP(board.ops[BOARD_OP_DRIVER_SETUP]);
EXECUTE_BOARD_OP(board.ops[BOARD_OP_LATE_INIT]);
board->driver_setup();
board->late_init();
printk("board late_init() passed!");
printk("Passed board initialization!");
printk("Welcome to uniLoader!");
/* Copy kernel to memory and boot */
printk("Booting linux...");