mirror of
https://github.com/ivoszbg/uniLoader.git
synced 2024-11-21 11:30:06 +00:00
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:
parent
b301e51432
commit
81d26edaa3
4
.gitignore
vendored
4
.gitignore
vendored
@ -14,3 +14,7 @@ lib/*.a*
|
||||
include/config/auto.conf
|
||||
include/generated/autoconf.h
|
||||
include/config
|
||||
boot.img
|
||||
blob/Image
|
||||
blob/dtb
|
||||
drivers/*.a
|
||||
|
10
Makefile
10
Makefile
@ -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
|
||||
|
@ -16,7 +16,7 @@ SECTIONS
|
||||
arch/aarch64/start.o
|
||||
}
|
||||
|
||||
.text : {
|
||||
.text ALIGN(4096) : {
|
||||
*(.text)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)"
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 >a4xl_board; // Return the correct board based on runtime config
|
||||
REGISTER_DRIVER("simplefb", simplefb_probe, &simplefb_data);
|
||||
return 0;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
2
drivers/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
# the drivers registration framework
|
||||
lib-y += framework.o
|
13
drivers/framework.c
Normal file
13
drivers/framework.c
Normal 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
|
@ -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_
|
||||
|
33
include/drivers/framework.h
Normal file
33
include/drivers/framework.h
Normal 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_
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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
24
lib/unic/stdint.h
Normal 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
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
35
main/main.c
35
main/main.c
@ -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...");
|
||||
|
Loading…
Reference in New Issue
Block a user