l4re-base-25.08.0

This commit is contained in:
2025-09-12 15:55:45 +02:00
commit d959eaab98
37938 changed files with 9382688 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
PKGDIR = ..
L4DIR ?= $(PKGDIR)/../..
TARGET = include src
include $(L4DIR)/mk/subdir.mk
src: include

View File

@@ -0,0 +1,6 @@
PKGDIR = ../..
L4DIR ?= $(PKGDIR)/../..
PKGNAME = drivers
include $(L4DIR)/mk/include.mk

View File

@@ -0,0 +1,117 @@
#ifndef L4_PPC32_OF_H__
#define L4_PPC32_OF_H__
#include <stdarg.h>
#include <string.h>
namespace L4_drivers
{
class Of
{
private:
/* declarations */
struct prom_args
{
const char *service;
int nargs;
int nret;
void *args[10];
prom_args(const char *s, int na, int nr) : service(s), nargs(na), nret(nr) {}
};
typedef int (*prom_entry)(struct prom_args *);
//int prom_call(const char *service, int nargs, int nret, ...) const;
protected:
enum {
PROM_ERROR = -1u
};
typedef void *ihandle_t;
typedef void *phandle_t;
typedef struct
{
unsigned long len;
char data[];
} of_item_t;
/* methods */
unsigned long prom_call(const char *service, int nargs, int nret, ...) const
{
struct prom_args args = prom_args(service, nargs, nret);
va_list list;
va_start(list, nret);
for(int i = 0; i < nargs; i++)
args.args[i] = va_arg(list, void*);
va_end(list);
for(int i = 0; i < nret; i++)
args.args[nargs + i] = 0;
if(_prom()(&args) < 0)
return PROM_ERROR;
return (nret > 0) ? (unsigned long)args.args[nargs] : 0;
}
int prom_getprop(phandle_t node, const char *pname, void *value,
size_t size)
{
return prom_call("getprop", 4, 1, node, pname, (unsigned long)value,
(unsigned long)size);
}
int prom_next_node(phandle_t *nodep)
{
phandle_t node;
if ((node = *nodep) != 0
&& (*nodep = (phandle_t)prom_call("child", 1, 1, node)) != 0)
return 1;
if ((*nodep = (phandle_t)prom_call("peer", 1, 1, node)) != 0)
return 1;
for (;;) {
if ((node = (phandle_t)prom_call("parent", 1, 1, node)) == 0)
return 0;
if ((*nodep = (phandle_t)prom_call("peer", 1, 1, node)) != 0)
return 1;
}
}
template<typename T>
static inline bool handle_valid(T p)
{
return ((unsigned long)p != 0 && (unsigned long)p != PROM_ERROR);
}
static prom_entry _prom(unsigned long prom = 0)
{
static prom_entry local_prom;
if(prom)
local_prom = reinterpret_cast<prom_entry>(prom);
return local_prom;
}
public:
Of() {};
static void set_prom(unsigned long prom)
{
_prom(prom);
}
static unsigned long get_prom()
{
return reinterpret_cast<unsigned long>(_prom());
}
};
}
#endif /* L4_PPC32_OF_H__*/

View File

@@ -0,0 +1,24 @@
#ifndef _L4_PPC32_OF_DEV_H__
#define _L4_PPC32_OF_DEV_H__
enum
{
MAX_OF_DEVICES = 32
};
typedef struct of_device_t
{
char type[32]; //type name
char name[32]; //device name
unsigned long reg; //address
union {
struct {
unsigned long cpu_freq;
unsigned long bus_freq;
unsigned long time_freq;
} freq;
unsigned long interrupts[3]; //pin, int nr, sense
};
} of_device_t;
#endif

View File

@@ -0,0 +1,40 @@
#include <l4/drivers/of.h>
#include <stdio.h>
namespace L4_drivers
{
class Of_if : public Of
{
private:
phandle_t _chosen;
ihandle_t _root;
phandle_t get_device(const char*, const char *prop = "device_type");
unsigned long cpu_detect(const char *prop);
public:
Of_if() : Of(), _chosen(0), _root(0) {}
unsigned long detect_ramsize();
unsigned long detect_cpu_freq();
unsigned long detect_bus_freq();
unsigned long detect_time_freq();
bool detect_devices(unsigned long *start_addr, unsigned long *length);
void boot_finish();
phandle_t get_chosen()
{
if(handle_valid(_chosen)) return _chosen;
_chosen = (phandle_t)prom_call("finddevice", 1, 1, "/chosen");
return _chosen;
}
ihandle_t get_root()
{
if(handle_valid(_root)) return _root;
_root = (ihandle_t)prom_call("finddevice", 1, 1, "/");
return _root;
}
void vesa_set_mode(int mode);
};
}

View File

@@ -0,0 +1,13 @@
PKGDIR ?= ../..
L4DIR ?= $(PKGDIR)/../..
SRC_CC := of.cc
SYSTEMS = $(SYSTEMS_PLAIN)
TARGET = libdrivers_of.a
PC_FILENAME = drivers_of
PRIVATE_INCDIR += $(SRC_DIR)/../include
include $(L4DIR)/mk/lib.mk
CXXFLAGS += -DL4_NO_RTTI -fno-exceptions -fno-rtti

View File

@@ -0,0 +1,152 @@
#include "of_if.h"
#include <l4/drivers/of_dev.h>
namespace L4_drivers
{
unsigned long Of_if::detect_ramsize()
{
unsigned long addr_cells, size_cells, ram_size;
unsigned long reg[100];
phandle_t mem;
prom_getprop(get_root(), "#address-cells", &addr_cells, sizeof(&addr_cells));
prom_getprop(get_root(), "#size-cells", &size_cells, sizeof(&size_cells));
ram_size = 0;
mem = get_device("memory");
unsigned int len = prom_getprop(mem, "reg", &reg, sizeof(reg));
len /= 4; /* always 32 bit values */
if(len > sizeof(reg))
len = sizeof(reg);
unsigned long base, size;
for(unsigned i = 0; i < len; i += (addr_cells + size_cells)) {
base = reg[i + addr_cells - 1];
size = reg[i + addr_cells + size_cells - 1];
if((base + size) > ram_size)
ram_size = base + size;
printf(" Memory base: [%08lx; %08lx] size: %lu KB\n",
base, base + size, size / 1024);
}
return ram_size;
}
unsigned long Of_if::cpu_detect(const char* prop)
{
phandle_t cpu;
unsigned long val;
cpu = get_device("cpu");
prom_getprop(cpu, prop, &val, sizeof(&val));
return val;
}
unsigned long Of_if::detect_bus_freq()
{
return cpu_detect("bus-frequency");
}
unsigned long Of_if::detect_cpu_freq()
{
return cpu_detect("clock-frequency");
}
unsigned long Of_if::detect_time_freq()
{
return cpu_detect("timebase-frequency");
}
L4_drivers::Of_if::phandle_t Of_if::get_device(const char *device, const char *prop)
{
phandle_t dev;
char type[32];
for(dev = 0; prom_next_node(&dev); )
{
prom_getprop(dev, prop, type, sizeof(type));
if (strcmp(type, device))
continue;
return dev;
}
return 0;
}
bool Of_if::detect_devices(unsigned long *start_addr, unsigned long *length)
{
static of_device_t dev[MAX_OF_DEVICES];
char descr[64];
printf(" Detecting hardware ...\n");
int i = -1;
for(phandle_t node = 0; prom_next_node(&node) && i < MAX_OF_DEVICES-1;)
{
if (prom_getprop(node, "device_type", &(dev[i+1].type),
sizeof(dev[i].type)) < 0)
continue;
i++;
prom_getprop(node, "name", &dev[i].name, sizeof(dev[i].name));
if (prom_getprop(node, "reg", &(dev[i].reg), sizeof(dev[i].reg)) < 0)
dev[i].reg = 0;
if (!strcmp(dev[i].type, "cpu"))
{
dev[i].freq.cpu_freq = detect_cpu_freq();
dev[i].freq.bus_freq = detect_bus_freq();
dev[i].freq.time_freq = detect_time_freq();
}
else if (prom_getprop(node, "interrupts", (dev[i].interrupts),
sizeof(dev[i].interrupts)) < 0)
dev[i].interrupts[0] = dev[i].interrupts[1] = dev[i].interrupts[2] = ~0UL;
//just for information
prom_getprop(node, ".description", descr, sizeof(descr));
printf("\33[1;36m"
" [%s]\33[0;36m (%s)\33[0m\n"
" reg: %08lx interrupts: %08lx, %08lx, %08lx\n",
dev[i].name, descr, dev[i].reg, dev[i].interrupts[0],
dev[i].interrupts[1], dev[i].interrupts[2]);
}
if (i < 0)
return false;
*start_addr = (unsigned long)dev;
*length = (i + 1) * sizeof(of_device_t);
return true;
}
void Of_if::boot_finish()
{
ihandle_t _std;
//close stdin
prom_getprop(get_chosen(), "stdin", &_std, sizeof(_std));
prom_call("close", 1, 0, _std);
//close stdout
prom_getprop(get_chosen(), "stdout", &_std, sizeof(_std));
prom_call("close", 1, 0, _std);
//finish pending dma requests
prom_call("quiesce", 0, 0);
}
void Of_if::vesa_set_mode(int mode)
{
(void)mode;
unsigned long test_mode = 0x117;
phandle_t disp = get_device("display", "name");
int ret = prom_call("vesa-set-mode", 2, 1, disp, test_mode);// &test_mode);
unsigned long adr = prom_call("vesa-frame-buffer-adr", 1, 1);
printf("VESA: returned %d fb %08lx\n", ret, adr);
}
}