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

View File

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

View File

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

View File

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

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x19050000 #define DECON_F_BASE 0x19050000
#define HW_SW_TRIG_CONTROL 0x70 #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 // Early initialization
static void c1s_init(void) int board_init(void)
{ {
/* Allow framebuffer to be written to */ /* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281; *(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
} }
// Late initialization // 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 struct {
// register_driver(&simplefb_driver); int width;
// Add more drivers here as needed int height;
} int stride;
void *address;
} simplefb_data = {
.width = 1080,
.height = 2400,
.stride = 4,
.address = (void *)0xf1000000
};
// Create the board_data structure for S5PV210 REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
static struct board_data c1s_board = { return 0;
.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
} }

View File

@ -3,39 +3,54 @@
* Copyright (c) 2022, Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com> * Copyright (c) 2022, Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
*/ */
#include <board.h> #include <board.h>
#include <drivers/framework.h>
#include <lib/simplefb.h>
#define DECON_F_BASE 0x12860000 #define DECON_F_BASE 0x12860000
#define HW_SW_TRIG_CONTROL 0x70 #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 // Early initialization
static void dreamlte_init(void) int board_init(void)
{ {
/* Allow framebuffer to be written to */ /* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281; *(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
} }
// Late initialization // 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 struct {
// register_driver(&simplefb_driver); int width;
// Add more drivers here as needed int height;
} int stride;
void *address;
} simplefb_data = {
.width = 1440,
.height = 2960,
.stride = 4,
.address = (void *)0xcc000000
};
// Create the board_data structure for S5PV210 REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
static struct board_data dreamlte_board = { return 0;
.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
} }

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x148b0000 #define DECON_F_BASE 0x148b0000
#define HW_SW_TRIG_CONTROL 0x70 #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 // Early initialization
static void gta4xl_init(void) int board_init(void)
{ {
/* Allow framebuffer to be written to */ /* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281; *(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
} }
// Late initialization // 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 struct {
// register_driver(&simplefb_driver); int width;
// Add more drivers here as needed int height;
} int stride;
void *address;
} simplefb_data = {
.width = 1200,
.height = 2000,
.stride = 4,
.address = (void *)0xca000000
};
// Create the board_data structure for S5PV210 REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
static struct board_data gta4xl_board = { return 0;
.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
} }

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x14830000 #define DECON_F_BASE 0x14830000
#define HW_SW_TRIG_CONTROL 0x70 #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 // Early initialization
static void j4lte_init(void) int board_init(void)
{ {
/* Allow framebuffer to be written to */ /* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281; *(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
} }
// Late initialization // 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 struct {
// register_driver(&simplefb_driver); int width;
// Add more drivers here as needed int height;
} int stride;
void *address;
} simplefb_data = {
.width = 720,
.height = 1280,
.stride = 4,
.address = (void *)0x67000000
};
// Create the board_data structure for S5PV210 REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
static struct board_data j4lte_board = { return 0;
.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
} }

View File

@ -5,6 +5,8 @@
#include <board.h> #include <board.h>
#include <main.h> #include <main.h>
#include <drivers/framework.h>
#include <lib/simplefb.h>
#define PIPE_SSPP_SRC_FORMAT 0x30 #define PIPE_SSPP_SRC_FORMAT 0x30
#define PIPE_SSPP_SRC_UNPACK_PATTERN 0x34 #define PIPE_SSPP_SRC_UNPACK_PATTERN 0x34
@ -14,37 +16,51 @@
#define MDP_CTL_0_BASE 0x1A02000 #define MDP_CTL_0_BASE 0x1A02000
#define MDP_CTL_FLUSH 0x18 #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 */ /* TODO: Doesn't really work :P */
writel(0x000236FF, PIPE_BASE + PIPE_SSPP_SRC_FORMAT); writel(0x000236FF, PIPE_BASE + PIPE_SSPP_SRC_FORMAT);
writel(0x03020001, PIPE_BASE + PIPE_SSPP_SRC_UNPACK_PATTERN); writel(0x03020001, PIPE_BASE + PIPE_SSPP_SRC_UNPACK_PATTERN);
writel((720 * 4), MDP_CTL_0_BASE + MDP_CTL_FLUSH); writel((720 * 4), MDP_CTL_0_BASE + MDP_CTL_FLUSH);
writel((1 << (0)), PIPE_BASE + PIPE_SSPP_SRC_YSTRIDE); writel((1 << (0)), PIPE_BASE + PIPE_SSPP_SRC_YSTRIDE);
return 0;
} }
// Late initialization // 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 struct {
// register_driver(&simplefb_driver); int width;
// Add more drivers here as needed int height;
} int stride;
void *address;
} simplefb_data = {
.width = 720,
.height = 1280,
.stride = 3,
.address = (void *)0x8e000000
};
// Create the board_data structure for S5PV210 REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
static struct board_data j5lte_board = { return 0;
.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
} }

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x14860000 #define DECON_F_BASE 0x14860000
#define HW_SW_TRIG_CONTROL 0x70 #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 // Early initialization
static void jackpotlte_init(void) int board_init(void)
{ {
/* Allow framebuffer to be written to */ /* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281; *(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
} }
// Late initialization // 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 struct {
// register_driver(&simplefb_driver); int width;
// Add more drivers here as needed int height;
} int stride;
void *address;
} simplefb_data = {
.width = 1080,
.height = 2200,
.stride = 4,
.address = (void *)0xec000000
};
// Create the board_data structure for S5PV210 REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
static struct board_data jackpotlte_board = { return 0;
.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
} }

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x13930000 #define DECON_F_BASE 0x13930000
#define HW_SW_TRIG_CONTROL 0x6b0 #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 // Early initialization
static void noblelte_init(void) int board_init(void)
{ {
/* Allow framebuffer to be written to */ /* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x2058; *(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x2058;
return 0;
} }
// Late initialization // 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 struct {
// register_driver(&simplefb_driver); int width;
// Add more drivers here as needed int height;
} int stride;
void *address;
} simplefb_data = {
.width = 1440,
.height = 2560,
.stride = 4,
.address = (void *)0xe2a00000
};
// Create the board_data structure for S5PV210 REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
static struct board_data noblelte_board = { return 0;
.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
} }

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x16030000 #define DECON_F_BASE 0x16030000
#define HW_SW_TRIG_CONTROL 0x70 #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 // Early initialization
static void starlte_init(void) int board_init(void)
{ {
/* Allow framebuffer to be written to */ /* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281; *(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
} }
// Late initialization // 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 struct {
// register_driver(&simplefb_driver); int width;
// Add more drivers here as needed int height;
} int stride;
void *address;
} simplefb_data = {
.width = 1440,
.height = 2960,
.stride = 4,
.address = (void *)0xcc000000
};
// Create the board_data structure for S5PV210 REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
static struct board_data starlte_board = { return 0;
.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
} }

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x19050000 #define DECON_F_BASE 0x19050000
#define HW_SW_TRIG_CONTROL 0x70 #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 // Early initialization
static void x1s_init(void) int board_init(void)
{ {
/* Allow framebuffer to be written to */ /* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281; *(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x1281;
return 0;
} }
// Late initialization // 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 struct {
// register_driver(&simplefb_driver); int width;
// Add more drivers here as needed int height;
} int stride;
void *address;
} simplefb_data = {
.width = 1440,
.height = 3200,
.stride = 4,
.address = (void *)0xf1000000
};
// Create the board_data structure for S5PV210 REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
static struct board_data x1s_board = { return 0;
.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
} }

View File

@ -8,35 +8,48 @@
#define DECON_F_BASE 0x13930000 #define DECON_F_BASE 0x13930000
#define HW_SW_TRIG_CONTROL 0x6b0 #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 // Early initialization
static void zeroflte_init(void) int board_init(void)
{ {
/* Allow framebuffer to be written to */ /* Allow framebuffer to be written to */
*(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x2058; *(int*) (DECON_F_BASE + HW_SW_TRIG_CONTROL) = 0x2058;
return 0;
} }
// Late initialization // 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 struct {
// register_driver(&simplefb_driver); int width;
// Add more drivers here as needed int height;
} int stride;
void *address;
} simplefb_data = {
.width = 1440,
.height = 2560,
.stride = 4,
.address = (void *)0xe2a00000
};
// Create the board_data structure for S5PV210 REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
static struct board_data zeroflte_board = { return 0;
.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
} }

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. * Well, well, well. We come back to this style again.
* TODO: Implement libfdt once we have C libs all sorted out. * TODO: Implement libfdt once we have C libs all sorted out.
* *
* @name -> board name * BOARD_OP_INIT -> initialization as soon as we hit C
* @init -> initialization as soon as we hit C * BOARD_OP_LATE_INIT -> late initialization
* @late_init -> late initialization * BOARD_OP_DRIVER_SETUP -> drivers setup
* @driver_setup -> driver initialization * 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 { struct board_data {
const char *name; const char *name;
void (*init)(void); int ops[BOARD_OP_EXIT];
void (*late_init)(void);
void (*driver_setup)(void);
}; };
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 int board_driver_setup(void);
extern struct board_data __attribute__((weak)) default_board; extern int board_init(void);
extern int board_late_init(void);
struct board_data default_board = { // Macro definitions for board operations
.name = "DEFAULT", #define EXECUTE_BOARD_OP(op_id) \
.init = NULL, // No init function for the default do { \
.late_init = NULL, switch (op_id) { \
.driver_setup = NULL, 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_ #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 */ #ifndef SIMPLEFB_H_ /* Include guard */
#define SIMPLEFB_H_ #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 { typedef struct _color {
unsigned char r; unsigned char r;
unsigned char g; unsigned char g;

View File

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

View File

@ -3,17 +3,9 @@
* Copyright (c) 2022, Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com> * Copyright (c) 2022, Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
*/ */
#include <lib/debug.h> #include <lib/debug.h>
#include <lib/simplefb.h>
#include <stddef.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) { void printk(char *text) {
#ifdef CONFIG_SIMPLE_FB #ifdef CONFIG_SIMPLE_FB
/* IMPORTANT: Limit the linecount */ /* IMPORTANT: Limit the linecount */

View File

@ -4,18 +4,23 @@
* Copyright (c) 2022, Markuss Broks <markuss.broks@gmail.com> * Copyright (c) 2022, Markuss Broks <markuss.broks@gmail.com>
* Copyright (c) 2022, Michael Srba <Michael.Srba@seznam.cz> * Copyright (c) 2022, Michael Srba <Michael.Srba@seznam.cz>
*/ */
#include <drivers/framework.h>
#include <lib/simplefb.h>
#include <lib/font.h> #include <lib/font.h>
#include <lib/simplefb.h>
#include <string.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)); memset(fb, 0x0, (width * height * stride));
} }
/* RGB888 format */ // 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) { * 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); long int location = (x * stride) + (y * width * stride);
#ifdef CONFIG_FRAMEBUFFER_BGRA #ifdef CONFIG_FRAMEBUFFER_BGRA
*(fb + location) = c.b; *(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 #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++) for (int i = x1; i < x2; i++)
draw_pixel(fb, i, y, width, stride, c); 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++) for (int i = y1; i < y2; i++)
draw_pixel(fb, x, i, width, stride, c); 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++) for (int i = y1; i < (y1 + h); i++)
draw_horizontal_line(fb, x1, (x1 + w), i, c, width, stride); 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 // loop through all characters in the text string
int l = strlen(text); 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++) { for (int x = 0; x < FONTW; x++) {
if (((b << x) & 0b10000000) > 0) 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; 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 *strchr(const char *s, int c);
char *strrchr(const char *s, int c); char *strrchr(const char *s, int c);
long atol(const char *s); long atol(const char *s);
void writel(unsigned int value, void* address);
static inline int tolower(int c) static inline int tolower(int c)
{ {

View File

@ -7,21 +7,32 @@
#include <main.h> #include <main.h>
#include <string.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 */ /* 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 */ EXECUTE_BOARD_OP(board.ops[BOARD_OP_INIT]);
#ifdef CONFIG_SIMPLE_FB EXECUTE_BOARD_OP(board.ops[BOARD_OP_DRIVER_SETUP]);
clean_fb((char*)CONFIG_FRAMEBUFFER_BASE, CONFIG_FRAMEBUFFER_WIDTH, CONFIG_FRAMEBUFFER_HEIGHT, CONFIG_FRAMEBUFFER_STRIDE); EXECUTE_BOARD_OP(board.ops[BOARD_OP_LATE_INIT]);
#endif
board->init();
printk("board init() passed!");
board->driver_setup(); printk("Passed board initialization!");
printk("Welcome to uniLoader!");
board->late_init();
printk("board late_init() passed!");
/* Copy kernel to memory and boot */ /* Copy kernel to memory and boot */
printk("Booting linux..."); printk("Booting linux...");