did some stuff, will probably refactor later
This commit is contained in:
parent
10ee4fcbd9
commit
bc4ec556e2
46 changed files with 1013 additions and 35635 deletions
8
Makefile
8
Makefile
|
@ -46,7 +46,13 @@ LIVESD := $(RELEASE_DIR)/aurix-$(GITREV)-livesd_$(ARCH)-$(PLATFORM).img
|
||||||
QEMU_FLAGS := -m 2G -smp 4 -serial stdio
|
QEMU_FLAGS := -m 2G -smp 4 -serial stdio
|
||||||
|
|
||||||
# QEMU Audio support
|
# QEMU Audio support
|
||||||
QEMU_FLAGS += -audiodev coreaudio,id=coreaudio0 -device ich9-intel-hda -device hda-output,audiodev=coreaudio0
|
#QEMU_FLAGS += -audiodev coreaudio,id=coreaudio0 -device ich9-intel-hda -device hda-output,audiodev=coreaudio0
|
||||||
|
|
||||||
|
# QEMU Mouse support
|
||||||
|
QEMU_FLAGS += -usb -device usb-mouse
|
||||||
|
|
||||||
|
# x86_64
|
||||||
|
QEMU_FLAGS += -machine q35
|
||||||
|
|
||||||
##
|
##
|
||||||
# General info
|
# General info
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#define COM1 0x3f8
|
#define COM1 0x3f8
|
||||||
|
|
||||||
void uart_init(uint16_t baud_rate)
|
void uart_init(uint32_t baud_rate)
|
||||||
{
|
{
|
||||||
uint8_t divisor = 115200 / baud_rate;
|
uint8_t divisor = 115200 / baud_rate;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
[AxBoot]
|
;; please leave this here, the parser breaks without it
|
||||||
|
|
||||||
default = 0
|
default = 0
|
||||||
timer=30
|
timeout = 30
|
||||||
|
|
||||||
[AurixOS]
|
[AurixOS]
|
||||||
protocol = aurix
|
protocol = aurix
|
||||||
image="boot:///System/axkrnl.sys"
|
image = boot:///System/axkrnl.sys
|
||||||
|
|
||||||
;; UEFI only
|
|
||||||
[Windows 10]
|
[Windows 10]
|
||||||
protocol = efi-chainload
|
protocol = efi-chainload
|
||||||
image="boot:///EFI/Microsoft/bootmgfw.efi"
|
image = boot:///EFI/Microsoft/bootmgfw.efi
|
|
@ -17,7 +17,10 @@
|
||||||
/* SOFTWARE. */
|
/* SOFTWARE. */
|
||||||
/*********************************************************************************/
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#include <config/config.h>
|
||||||
|
#include <config/ini.h>
|
||||||
#include <lib/string.h>
|
#include <lib/string.h>
|
||||||
|
#include <loader/loader.h>
|
||||||
#include <mm/mman.h>
|
#include <mm/mman.h>
|
||||||
#include <vfs/vfs.h>
|
#include <vfs/vfs.h>
|
||||||
#include <print.h>
|
#include <print.h>
|
||||||
|
@ -26,20 +29,47 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define DEFAULT_ENTRY 0
|
||||||
|
#define DEFAULT_TIMEOUT 30
|
||||||
|
|
||||||
char *config_paths[] = {
|
char *config_paths[] = {
|
||||||
|
"\\AxBoot\\axboot.cfg",
|
||||||
"\\axboot.cfg",
|
"\\axboot.cfg",
|
||||||
"\\System\\axboot.cfg",
|
|
||||||
"\\EFI\\axboot.cfg",
|
"\\EFI\\axboot.cfg",
|
||||||
"\\EFI\\BOOT\\axboot.cfg",
|
"\\EFI\\BOOT\\axboot.cfg",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct axboot_cfg cfg = {
|
||||||
|
.default_entry = DEFAULT_ENTRY,
|
||||||
|
.timeout = DEFAULT_TIMEOUT,
|
||||||
|
|
||||||
|
//.entry_count = 0
|
||||||
|
.entry_count = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
struct axboot_entry entries[2] = {
|
||||||
|
{
|
||||||
|
.name = "AurixOS",
|
||||||
|
.description = "Boot the Aurix Operating System",
|
||||||
|
.image_path = "\\System\\axkrnl",
|
||||||
|
.protocol = PROTO_AURIX
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "Windows 10",
|
||||||
|
.description = "",
|
||||||
|
.image_path = "\\EFI\\Microsoft\\bootmgfw.efi",
|
||||||
|
.protocol = PROTO_CHAINLOAD
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void config_init(void)
|
void config_init(void)
|
||||||
{
|
{
|
||||||
char *config_buf;
|
char *config_buf = NULL;
|
||||||
uint8_t open = 0;
|
uint8_t open = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < ARRAY_LENGTH(config_paths); i++) {
|
for (size_t i = 0; i < ARRAY_LENGTH(config_paths); i++) {
|
||||||
vfs_read("\\System\\axkrnl", &config_buf);
|
vfs_read(config_paths[i], &config_buf);
|
||||||
if (config_buf != NULL) {
|
if (config_buf != NULL) {
|
||||||
open = 1;
|
open = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -52,7 +82,25 @@ void config_init(void)
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: parse configuration file
|
|
||||||
|
|
||||||
mem_free(config_buf);
|
mem_free(config_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_get_timeout()
|
||||||
|
{
|
||||||
|
return cfg.timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
int config_get_default()
|
||||||
|
{
|
||||||
|
return cfg.default_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
int config_get_entry_count()
|
||||||
|
{
|
||||||
|
return cfg.entry_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct axboot_entry *config_get_entries()
|
||||||
|
{
|
||||||
|
return entries;
|
||||||
|
}
|
130
boot/common/data/list.c
Normal file
130
boot/common/data/list.c
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
/*********************************************************************************/
|
||||||
|
/* Module Name: list.c */
|
||||||
|
/* Project: AurixOS */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||||
|
/* */
|
||||||
|
/* This source is subject to the MIT License. */
|
||||||
|
/* See License.txt in the root of this repository. */
|
||||||
|
/* All other rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||||
|
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||||
|
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||||
|
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||||
|
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||||
|
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||||
|
/* SOFTWARE. */
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#include <data/list.h>
|
||||||
|
#include <mm/mman.h>
|
||||||
|
#include <print.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
List *list_new()
|
||||||
|
{
|
||||||
|
List *list = (List *)mem_alloc(sizeof(List));
|
||||||
|
if (!list) {
|
||||||
|
debug("list_new(): Failed to allocate memory for new list!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
list->count = 0;
|
||||||
|
list->root = (ListNode *)0;
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode *listnode_new(void *data)
|
||||||
|
{
|
||||||
|
ListNode *ln = (ListNode *)mem_alloc(sizeof(ListNode));
|
||||||
|
if (!ln) {
|
||||||
|
debug("listnode_new(): Failed to allocate memory for new list node!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ln->prev = (ListNode *)0;
|
||||||
|
ln->next = (ListNode *)0;
|
||||||
|
ln->data = data;
|
||||||
|
|
||||||
|
return ln;
|
||||||
|
}
|
||||||
|
|
||||||
|
int list_add(List *list, void *data)
|
||||||
|
{
|
||||||
|
ListNode *node = listnode_new(data);
|
||||||
|
if (!node) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!list->root) {
|
||||||
|
list->root = node;
|
||||||
|
} else {
|
||||||
|
ListNode *cur = list->root;
|
||||||
|
|
||||||
|
while (cur->next) {
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur->next = node;
|
||||||
|
node->prev = cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
list->count++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *list_remove_at(List *list, uint32_t idx)
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
|
||||||
|
if (!list || list->count == 0 || idx >= list->count) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode *cur = list->root;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; (i < idx) && cur; i++) {
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cur) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = cur->data;
|
||||||
|
|
||||||
|
if (cur->prev) {
|
||||||
|
cur->prev->next = cur->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur->next) {
|
||||||
|
cur->next->prev = cur->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx == 0) {
|
||||||
|
list->root = cur->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_free(cur);
|
||||||
|
|
||||||
|
list->count--;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *list_get_at(List *list, uint32_t idx)
|
||||||
|
{
|
||||||
|
if (!list || list->count == 0 | idx >= list->count) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode *cur = list->root;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; (i < idx) && cur; i++) {
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cur ? cur->data : NULL;
|
||||||
|
}
|
|
@ -17,9 +17,13 @@
|
||||||
/* SOFTWARE. */
|
/* SOFTWARE. */
|
||||||
/*********************************************************************************/
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#include <config/config.h>
|
||||||
|
#include <loader/loader.h>
|
||||||
|
#include <proto/aurix.h>
|
||||||
#include <uart/uart.h>
|
#include <uart/uart.h>
|
||||||
#include <vfs/vfs.h>
|
#include <vfs/vfs.h>
|
||||||
#include <ui/ui.h>
|
#include <ui/ui.h>
|
||||||
|
#include <axboot.h>
|
||||||
#include <print.h>
|
#include <print.h>
|
||||||
|
|
||||||
void axboot_init()
|
void axboot_init()
|
||||||
|
@ -32,5 +36,20 @@ void axboot_init()
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_init();
|
//config_init();
|
||||||
|
|
||||||
|
//ui_init();
|
||||||
|
|
||||||
|
//debug("axboot_init(): Returned from main menu, something went wrong. Halting!");
|
||||||
|
//UNREACHABLE();
|
||||||
|
|
||||||
|
// just boot aurixos for now
|
||||||
|
struct axboot_entry axos = {
|
||||||
|
.name = "AurixOS",
|
||||||
|
.description = "",
|
||||||
|
.image_path = "\\System\\axkrnl",
|
||||||
|
.protocol = PROTO_AURIX
|
||||||
|
};
|
||||||
|
loader_load(&axos);
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
|
@ -143,6 +143,38 @@ char *strcpy(char *dest, const char *src)
|
||||||
return pdest;
|
return pdest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *strncpy(char *dest, const char *src, size_t n)
|
||||||
|
{
|
||||||
|
if (dest == NULL || src == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *pdest = dest;
|
||||||
|
|
||||||
|
while (*src != '\0' || n--) {
|
||||||
|
*pdest++ = *src++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pdest = '\0';
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *strncat(char *dest, const char *src, size_t n)
|
||||||
|
{
|
||||||
|
if (dest == 0 || src == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i = strlen(dest);
|
||||||
|
size_t a = 0;
|
||||||
|
|
||||||
|
while (a < n && src[a] != '\0') {
|
||||||
|
dest[i++] = src[a++];
|
||||||
|
}
|
||||||
|
dest[i] = '\0';
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Get rid of this function
|
// TODO: Get rid of this function
|
||||||
char *strdup(const char *s)
|
char *strdup(const char *s)
|
||||||
{
|
{
|
||||||
|
|
58
boot/common/loader/loader.c
Normal file
58
boot/common/loader/loader.c
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/*********************************************************************************/
|
||||||
|
/* Module Name: loader.c */
|
||||||
|
/* Project: AurixOS */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||||
|
/* */
|
||||||
|
/* This source is subject to the MIT License. */
|
||||||
|
/* See License.txt in the root of this repository. */
|
||||||
|
/* All other rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||||
|
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||||
|
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||||
|
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||||
|
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||||
|
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||||
|
/* SOFTWARE. */
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#include <config/config.h>
|
||||||
|
#include <loader/loader.h>
|
||||||
|
#include <lib/string.h>
|
||||||
|
#include <proto/aurix.h>
|
||||||
|
#include <print.h>
|
||||||
|
#include <axboot.h>
|
||||||
|
|
||||||
|
int proto_str_to_int(char *proto)
|
||||||
|
{
|
||||||
|
if (strcmp(proto, "aurix") == 0) {
|
||||||
|
return PROTO_AURIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef AXBOOT_UEFI
|
||||||
|
if (strcmp(proto, "efi-chainload") == 0) {
|
||||||
|
return PROTO_CHAINLOAD;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return PROTO_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loader_load(struct axboot_entry *entry)
|
||||||
|
{
|
||||||
|
debug("loader_load(): Booting \"%s\"...\n", entry->name);
|
||||||
|
|
||||||
|
switch (entry->protocol) {
|
||||||
|
case PROTO_AURIX: {
|
||||||
|
aurix_load(entry->image_path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
debug("Entry doesn't have a supported protocol!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
|
@ -113,6 +113,7 @@ void *mem_alloc(size_t n)
|
||||||
|
|
||||||
add_alloc(alloc, n);
|
add_alloc(alloc, n);
|
||||||
|
|
||||||
|
debug("mem_alloc(): Allocated %u bytes\n", n);
|
||||||
return alloc;
|
return alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ int mem_allocat(void *addr, size_t npages)
|
||||||
|
|
||||||
status = gBootServices->AllocatePages(AllocateAddress, EfiLoaderData, (EFI_UINTN)npages, addr);
|
status = gBootServices->AllocatePages(AllocateAddress, EfiLoaderData, (EFI_UINTN)npages, addr);
|
||||||
if (EFI_ERROR(status)) {
|
if (EFI_ERROR(status)) {
|
||||||
debug("mem_allocat(): Couldn't allocate %u bytes at 0x%lx: %s (%lx)\n", npages, addr, efi_status_to_str(status), status);
|
debug("mem_allocat(): Couldn't allocate %u pages at 0x%lx: %s (%lx)\n", npages, addr, efi_status_to_str(status), status);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,9 +138,9 @@ void *mem_realloc(void *addr, size_t n)
|
||||||
void *new = NULL;
|
void *new = NULL;
|
||||||
|
|
||||||
int i = find_alloc(addr);
|
int i = find_alloc(addr);
|
||||||
if (i == -1) {
|
if (i == -1 || addr == NULL) {
|
||||||
debug("mem_realloc(): Couldn't find allocation for 0x%lx.\n");
|
debug("mem_realloc(): Couldn't find allocation for 0x%lx, allocating new memory.\n");
|
||||||
return NULL;
|
return mem_alloc(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
old_size = allocation_list[i].size;
|
old_size = allocation_list[i].size;
|
||||||
|
@ -169,6 +170,8 @@ void mem_free(void *addr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug("mem_free(): Freed 0x%llx\n", addr);
|
||||||
|
|
||||||
remove_alloc(addr);
|
remove_alloc(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,62 @@
|
||||||
/* SOFTWARE. */
|
/* SOFTWARE. */
|
||||||
/*********************************************************************************/
|
/*********************************************************************************/
|
||||||
|
|
||||||
#include <mm/mman.h>
|
// TODO: Remove this if statement once I fix stb_truetype compilation
|
||||||
|
#if 0
|
||||||
|
|
||||||
//#define STBTT_malloc(x,u) ((void)(u),mem_alloc(x))
|
#include <mm/mman.h>
|
||||||
//#define STBTT_free(x,u) ((void)(u),mem_free(x))
|
#include <arch/lib/math.h>
|
||||||
//#define STB_TRUETYPE_IMPLEMENTATION
|
#include <lib/string.h>
|
||||||
//#include <ui/stb_truetype.h>
|
#include <lib/assert.h>
|
||||||
|
#include <vfs/vfs.h>
|
||||||
|
#include <print.h>
|
||||||
|
|
||||||
|
__attribute__((used)) static volatile int _fltused = 0;
|
||||||
|
|
||||||
|
#define STB_TRUETYPE_IMPLEMENTATION
|
||||||
|
|
||||||
|
#define STBTT_ifloor(x) _ifloor(x)
|
||||||
|
#define STBTT_iceil(x) _iceil(x)
|
||||||
|
#define STBTT_sqrt(x) _sqrt(x)
|
||||||
|
#define STBTT_pow(x, y) _pow(x, y)
|
||||||
|
#define STBTT_fmod(x, y) _fmod(x, y)
|
||||||
|
#define STBTT_cos(x) _cos(x)
|
||||||
|
#define STBTT_acos(x) _acos(x)
|
||||||
|
#define STBTT_fabs(x) __builtin_fabs(x)
|
||||||
|
|
||||||
|
#define STBTT_malloc(x, u) ((void)(u), mem_alloc(x))
|
||||||
|
#define STBTT_free(x, u) ((void)(u), mem_free(x))
|
||||||
|
|
||||||
|
#define STBTT_assert(x) assert(x, #x)
|
||||||
|
#define STBTT_strlen(x) strlen(x)
|
||||||
|
|
||||||
|
#define STBTT_memcpy memcpy
|
||||||
|
#define STBTT_memset memset
|
||||||
|
|
||||||
|
#include "stb_truetype.h"
|
||||||
|
|
||||||
|
unsigned char *font_buf = NULL;
|
||||||
|
stbtt_fontinfo font_info;
|
||||||
|
float font_scale;
|
||||||
|
int font_ascent, font_descent;
|
||||||
|
int font_linegap;
|
||||||
|
int font_size;
|
||||||
|
|
||||||
|
void font_init(char *font_path, int initial_size)
|
||||||
|
{
|
||||||
|
vfs_read(font_path, &font_buf);
|
||||||
|
if (!font_buf) {
|
||||||
|
debug("Font not loaded, returning...\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
font_size = initial_size;
|
||||||
|
|
||||||
|
stbtt_InitFont(&font_info, &font_buf, 0);
|
||||||
|
font_scale = stbtt_ScaleForPixelHeight(&font_info, font_size);
|
||||||
|
stbtt_GetFontVMetrics(&font_info, &font_ascent, &font_descent, &font_linegap);
|
||||||
|
font_ascent *= font_scale;
|
||||||
|
font_descent *= font_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -18,39 +18,39 @@
|
||||||
/*********************************************************************************/
|
/*********************************************************************************/
|
||||||
|
|
||||||
#include <ui/framebuffer.h>
|
#include <ui/framebuffer.h>
|
||||||
|
#include <ui/mouse.h>
|
||||||
|
#include <ui/font.h>
|
||||||
|
#include <ui/ui.h>
|
||||||
|
#include <config/config.h>
|
||||||
|
|
||||||
#include <print.h>
|
#include <print.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct ui_config {
|
|
||||||
uintptr_t fb_addr;
|
|
||||||
struct fb_mode *fb_modes;
|
|
||||||
int total_modes;
|
|
||||||
int current_mode;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ui_config config;
|
|
||||||
|
|
||||||
void ui_init()
|
void ui_init()
|
||||||
{
|
{
|
||||||
struct fb_mode *available_fb_modes = NULL;
|
struct ui_context ctx;
|
||||||
int total_modes = 0;
|
|
||||||
int current_mode = 0;
|
|
||||||
|
|
||||||
if (!get_framebuffer(&config.fb_addr, &config.fb_modes, &config.total_modes, &config.current_mode)) {
|
if (!get_framebuffer(&ctx.fb_addr, &ctx.fb_modes, &ctx.total_modes, &ctx.current_mode)) {
|
||||||
debug("Failed to acquire a framebuffer!\n");
|
debug("Failed to acquire a framebuffer!\n");
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("Dumping framebuffer information\n");
|
debug("Dumping framebuffer information\n");
|
||||||
debug("--------------------------------\n");
|
debug("--------------------------------\n");
|
||||||
debug("Address: 0x%llx\n", config.fb_addr);
|
debug("Address: 0x%llx\n", ctx.fb_addr);
|
||||||
|
|
||||||
for (int i = 0; i < config.total_modes; i++) {
|
for (int i = 0; i < ctx.total_modes; i++) {
|
||||||
debug("\nMode %u:%s\n", i, (i == config.current_mode) ? " (current)" : "");
|
debug("\nMode %u:%s\n", i, (i == ctx.current_mode) ? " (current)" : "");
|
||||||
debug("Resolution: %ux%u\n", config.fb_modes[i].width, config.fb_modes[i].height);
|
debug("Resolution: %ux%u\n", ctx.fb_modes[i].width, ctx.fb_modes[i].height);
|
||||||
debug("Bits Per Pixel: %u\n", config.fb_modes[i].bpp);
|
debug("Bits Per Pixel: %u\n", ctx.fb_modes[i].bpp);
|
||||||
debug("Pitch: %u\n", config.fb_modes[i].pitch);
|
debug("Pitch: %u\n", ctx.fb_modes[i].pitch);
|
||||||
|
debug("Format: %s\n", ctx.fb_modes[i].format == FB_RGBA ? "RGBA" : "BGRA");
|
||||||
}
|
}
|
||||||
|
|
||||||
while(1);
|
//font_init("\\AxBoot\\fonts\\DreamOrphans.ttf", 20);
|
||||||
|
|
||||||
|
//while (1) {
|
||||||
|
//get_mouse(&m_x, &m_y, &m_but);
|
||||||
|
//debug("Mouse X = %u | Mouse Y = %u\n", m_x, m_y);
|
||||||
|
//}
|
||||||
}
|
}
|
94
boot/include/arch/x86_64/arch/lib/math.h
Normal file
94
boot/include/arch/x86_64/arch/lib/math.h
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/*********************************************************************************/
|
||||||
|
/* Module Name: math.h */
|
||||||
|
/* Project: AurixOS */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||||
|
/* */
|
||||||
|
/* This source is subject to the MIT License. */
|
||||||
|
/* See License.txt in the root of this repository. */
|
||||||
|
/* All other rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||||
|
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||||
|
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||||
|
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||||
|
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||||
|
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||||
|
/* SOFTWARE. */
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _ARCH_LIB_MATH_H
|
||||||
|
#define _ARCH_LIB_MATH_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
static double _sqrt(double n)
|
||||||
|
{
|
||||||
|
double out;
|
||||||
|
__asm__ volatile("fldl %[input];"
|
||||||
|
"fsqrt;"
|
||||||
|
"fstpl %[output];"
|
||||||
|
: [ output ] "=g"(out)
|
||||||
|
: [ input ] "g"(n)
|
||||||
|
:);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double _cos(double n)
|
||||||
|
{
|
||||||
|
double out;
|
||||||
|
__asm__ volatile("fldl %[input];"
|
||||||
|
"fcos;"
|
||||||
|
"fstpl %[output];"
|
||||||
|
: [ output ] "=g"(out)
|
||||||
|
: [ input ] "g"(n)
|
||||||
|
:);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double _acos(double n)
|
||||||
|
{
|
||||||
|
double imd = _sqrt(1 - (n * n));
|
||||||
|
double out;
|
||||||
|
__asm__ volatile("fldl %[imd];"
|
||||||
|
"fldl %[input];"
|
||||||
|
"fpatan;"
|
||||||
|
"fstpl %[output];"
|
||||||
|
: [ output ] "=g"(out)
|
||||||
|
: [ input ] "g"(n), [ imd ] "g"(imd)
|
||||||
|
:);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _ifloor(double d)
|
||||||
|
{
|
||||||
|
if ((((double)((int)d)) == d) || (d >= 0))
|
||||||
|
return (int)d;
|
||||||
|
return (int)(d - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _iceil(double d)
|
||||||
|
{
|
||||||
|
if ((((double)((int)d)) == d) || (d < 0))
|
||||||
|
return (int)d;
|
||||||
|
return (int)(d + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double _pow(double a, int n)
|
||||||
|
{
|
||||||
|
double prod = 1;
|
||||||
|
bool neg = (n < 0);
|
||||||
|
n = neg ? -n : n;
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
prod = prod * a;
|
||||||
|
if (neg)
|
||||||
|
prod = 1 / prod;
|
||||||
|
return prod;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double _fmod(double x, double y)
|
||||||
|
{
|
||||||
|
return x - ((int)(x / y)) * y;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _ARCH_LIB_MATH_H */
|
|
@ -29,6 +29,9 @@
|
||||||
#define UNREACHABLE() __builtin_unreachable()
|
#define UNREACHABLE() __builtin_unreachable()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO: This is hacky
|
||||||
|
#define axboot_halt() while (1);
|
||||||
|
|
||||||
void axboot_init(void);
|
void axboot_init(void);
|
||||||
|
|
||||||
#endif /* _AXBOOT_H */
|
#endif /* _AXBOOT_H */
|
42
boot/include/config/config.h
Normal file
42
boot/include/config/config.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*********************************************************************************/
|
||||||
|
/* Module Name: config.h */
|
||||||
|
/* Project: AurixOS */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||||
|
/* */
|
||||||
|
/* This source is subject to the MIT License. */
|
||||||
|
/* See License.txt in the root of this repository. */
|
||||||
|
/* All other rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||||
|
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||||
|
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||||
|
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||||
|
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||||
|
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||||
|
/* SOFTWARE. */
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _CONFIG_CONFIG_H
|
||||||
|
#define _CONFIG_CONFIG_H
|
||||||
|
|
||||||
|
struct axboot_cfg {
|
||||||
|
// overridable stuff
|
||||||
|
int default_entry;
|
||||||
|
int timeout;
|
||||||
|
|
||||||
|
int entry_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct axboot_entry {
|
||||||
|
char *name;
|
||||||
|
char *description;
|
||||||
|
char *image_path;
|
||||||
|
int protocol;
|
||||||
|
};
|
||||||
|
|
||||||
|
void config_init(void);
|
||||||
|
|
||||||
|
int config_get_entry_count();
|
||||||
|
|
||||||
|
#endif /* _CONFIG_CONFIG_H */
|
86
boot/include/config/ini.h
Normal file
86
boot/include/config/ini.h
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/*********************************************************************************/
|
||||||
|
/* Module Name: ini.h */
|
||||||
|
/* Project: AurixOS */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||||
|
/* */
|
||||||
|
/* This source is subject to the MIT License. */
|
||||||
|
/* See License.txt in the root of this repository. */
|
||||||
|
/* All other rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||||
|
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||||
|
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||||
|
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||||
|
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||||
|
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||||
|
/* SOFTWARE. */
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _CONFIG_INI_H
|
||||||
|
#define _CONFIG_INI_H
|
||||||
|
|
||||||
|
enum token_type {
|
||||||
|
SECTION,
|
||||||
|
KEY,
|
||||||
|
VALUE,
|
||||||
|
|
||||||
|
EOF,
|
||||||
|
ILLEGAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct string_view {
|
||||||
|
char *data;
|
||||||
|
unsigned int len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct token {
|
||||||
|
enum token_type type;
|
||||||
|
struct string_view lit;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct token_array {
|
||||||
|
struct token *items;
|
||||||
|
unsigned int count;
|
||||||
|
unsigned int capacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lexer {
|
||||||
|
char *input;
|
||||||
|
unsigned int pos;
|
||||||
|
unsigned int read_pos;
|
||||||
|
char ch;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct parser {
|
||||||
|
struct token_array *tokens;
|
||||||
|
unsigned int pos;
|
||||||
|
unsigned int read_pos;
|
||||||
|
struct token *cur_token;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct key_value {
|
||||||
|
struct string_view key;
|
||||||
|
struct string_view value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct section {
|
||||||
|
struct string_view name;
|
||||||
|
struct key_value *items;
|
||||||
|
unsigned int count;
|
||||||
|
unsigned int capacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ini_file {
|
||||||
|
struct section root;
|
||||||
|
struct section *items;
|
||||||
|
unsigned int count;
|
||||||
|
unsigned int capacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
void parse_ini(struct ini_file *ini, char *buf);
|
||||||
|
|
||||||
|
char *ini_get_value(struct ini_file *ini, char *section, char *key);
|
||||||
|
int ini_get_value_int(struct ini_file *ini, char *section, char *key);
|
||||||
|
|
||||||
|
#endif /* _CONFIG_INI_H */
|
41
boot/include/data/da.h
Normal file
41
boot/include/data/da.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*********************************************************************************/
|
||||||
|
/* Module Name: da.b */
|
||||||
|
/* Project: AurixOS */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||||
|
/* */
|
||||||
|
/* This source is subject to the MIT License. */
|
||||||
|
/* See License.txt in the root of this repository. */
|
||||||
|
/* All other rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||||
|
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||||
|
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||||
|
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||||
|
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||||
|
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||||
|
/* SOFTWARE. */
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _DATA_DA_H
|
||||||
|
#define _DATA_DA_H
|
||||||
|
|
||||||
|
#include <mm/mman.h>
|
||||||
|
#include <print.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <efilib.h>
|
||||||
|
|
||||||
|
#define DA_INIT_CAPACITY 8192
|
||||||
|
#define DA_REALLOC(oldptr, newsz) mem_realloc(oldptr, newsz)
|
||||||
|
|
||||||
|
#define da_append(da, item) \
|
||||||
|
do {\
|
||||||
|
if ((da)->count >= (da)->capacity) { \
|
||||||
|
size_t new_capacity = (da)->capacity + DA_INIT_CAPACITY; \
|
||||||
|
(da)->items = DA_REALLOC((da)->items, new_capacity * sizeof((da)->items[0])); \
|
||||||
|
(da)->capacity = new_capacity; \
|
||||||
|
} \
|
||||||
|
(da)->items[(da)->count++] = (item); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif /* _DATA_DA_H */
|
45
boot/include/data/list.h
Normal file
45
boot/include/data/list.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*********************************************************************************/
|
||||||
|
/* Module Name: list.h */
|
||||||
|
/* Project: AurixOS */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||||
|
/* */
|
||||||
|
/* This source is subject to the MIT License. */
|
||||||
|
/* See License.txt in the root of this repository. */
|
||||||
|
/* All other rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||||
|
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||||
|
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||||
|
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||||
|
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||||
|
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||||
|
/* SOFTWARE. */
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _DATA_LIST_H
|
||||||
|
#define _DATA_LIST_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct _ListNode {
|
||||||
|
void *data;
|
||||||
|
struct _ListNode *prev;
|
||||||
|
struct _ListNode *next;
|
||||||
|
} ListNode;
|
||||||
|
|
||||||
|
typedef struct _List {
|
||||||
|
uint32_t count;
|
||||||
|
ListNode *root;
|
||||||
|
} List;
|
||||||
|
|
||||||
|
List *list_new();
|
||||||
|
|
||||||
|
int list_add(List *list, void *data);
|
||||||
|
void *list_remove_at(List *list, uint32_t idx);
|
||||||
|
|
||||||
|
ListNode *listnode_new(void *data);
|
||||||
|
|
||||||
|
void *list_get_at(List *list, uint32_t idx);
|
||||||
|
|
||||||
|
#endif /* _DATA_LIST_H */
|
34
boot/include/lib/assert.h
Normal file
34
boot/include/lib/assert.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*********************************************************************************/
|
||||||
|
/* Module Name: assert.h */
|
||||||
|
/* Project: AurixOS */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||||
|
/* */
|
||||||
|
/* This source is subject to the MIT License. */
|
||||||
|
/* See License.txt in the root of this repository. */
|
||||||
|
/* All other rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||||
|
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||||
|
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||||
|
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||||
|
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||||
|
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||||
|
/* SOFTWARE. */
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _LIB_ASSERT_H
|
||||||
|
#define _LIB_ASSERT_H
|
||||||
|
|
||||||
|
#include <print.h>
|
||||||
|
#include <axboot.h>
|
||||||
|
|
||||||
|
#define assert(expr, msg) \
|
||||||
|
do { \
|
||||||
|
if (!!(expr)) { \
|
||||||
|
log("Assertion failed in file %s, line %u: %s\n", __FILE__, __LINE__, msg); \
|
||||||
|
axboot_halt(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif /* _LIB_ASSERT_H */
|
|
@ -30,6 +30,8 @@ size_t strlen(const char *str);
|
||||||
int strcmp(const char *s1, const char *s2);
|
int strcmp(const char *s1, const char *s2);
|
||||||
int strncmp(const char *s1, const char *s2, size_t n);
|
int strncmp(const char *s1, const char *s2, size_t n);
|
||||||
char *strcpy(char *dest, const char *src);
|
char *strcpy(char *dest, const char *src);
|
||||||
|
char *strncpy(char *dest, const char *src, size_t n);
|
||||||
|
char *strncat(char *dest, const char *src, size_t n);
|
||||||
char *strdup(const char *s);
|
char *strdup(const char *s);
|
||||||
char *strtok(char *str, const char *delim);
|
char *strtok(char *str, const char *delim);
|
||||||
char *strchr(char *s, int c);
|
char *strchr(char *s, int c);
|
||||||
|
|
36
boot/include/loader/loader.h
Normal file
36
boot/include/loader/loader.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*********************************************************************************/
|
||||||
|
/* Module Name: loader.h */
|
||||||
|
/* Project: AurixOS */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||||
|
/* */
|
||||||
|
/* This source is subject to the MIT License. */
|
||||||
|
/* See License.txt in the root of this repository. */
|
||||||
|
/* All other rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||||
|
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||||
|
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||||
|
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||||
|
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||||
|
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||||
|
/* SOFTWARE. */
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _LOADER_LOADER_H
|
||||||
|
#define _LOADER_LOADER_H
|
||||||
|
|
||||||
|
enum loader_protocol {
|
||||||
|
PROTO_AURIX,
|
||||||
|
#ifdef AXBOOT_UEFI
|
||||||
|
PROTO_CHAINLOAD,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PROTO_UNSUPPORTED
|
||||||
|
};
|
||||||
|
|
||||||
|
void loader_load(struct axboot_entry *entry);
|
||||||
|
|
||||||
|
int proto_str_to_int(char *proto);
|
||||||
|
|
||||||
|
#endif /* _LOADER_LOADER_H */
|
File diff suppressed because it is too large
Load diff
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void uart_init(uint16_t baud_rate);
|
void uart_init(uint32_t baud_rate);
|
||||||
|
|
||||||
void uart_send(char c);
|
void uart_send(char c);
|
||||||
void uart_sendstr(char *str);
|
void uart_sendstr(char *str);
|
||||||
|
|
25
boot/include/ui/font.h
Normal file
25
boot/include/ui/font.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*********************************************************************************/
|
||||||
|
/* Module Name: font.h */
|
||||||
|
/* Project: AurixOS */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||||
|
/* */
|
||||||
|
/* This source is subject to the MIT License. */
|
||||||
|
/* See License.txt in the root of this repository. */
|
||||||
|
/* All other rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||||
|
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||||
|
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||||
|
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||||
|
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||||
|
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||||
|
/* SOFTWARE. */
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _UI_FONT_H
|
||||||
|
#define _UI_FONT_H
|
||||||
|
|
||||||
|
void font_init(char *font_path, int initial_size);
|
||||||
|
|
||||||
|
#endif /* _UI_FONT_H */
|
|
@ -36,6 +36,6 @@ struct fb_mode {
|
||||||
int format;
|
int format;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool get_framebuffer(uintptr_t *fb_addr, struct fb_mode **available_modes, int *total_modes, int *current_mode_index);
|
bool get_framebuffer(uint32_t **fb_addr, struct fb_mode **available_modes, int *total_modes, int *current_mode_index);
|
||||||
|
|
||||||
#endif /* _UI_FRAMEBUFFER_H */
|
#endif /* _UI_FRAMEBUFFER_H */
|
31
boot/include/ui/mouse.h
Normal file
31
boot/include/ui/mouse.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*********************************************************************************/
|
||||||
|
/* Module Name: mouse.h */
|
||||||
|
/* Project: AurixOS */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||||
|
/* */
|
||||||
|
/* This source is subject to the MIT License. */
|
||||||
|
/* See License.txt in the root of this repository. */
|
||||||
|
/* All other rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||||
|
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||||
|
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||||
|
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||||
|
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||||
|
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||||
|
/* SOFTWARE. */
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _UI_MOUSE_H
|
||||||
|
#define _UI_MOUSE_H
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LEFT_MOUSE_BUTTON = 0x1,
|
||||||
|
MIDDLE_MOUSE_BUTTON = 0x2,
|
||||||
|
RIGHT_MOUSE_BUTTON = 0x4
|
||||||
|
};
|
||||||
|
|
||||||
|
void get_mouse(uint16_t *mouse_x, uint16_t *mouse_y, uint8_t *mouse_buttons);
|
||||||
|
|
||||||
|
#endif /* _UI_MOUSE_H */
|
|
@ -20,6 +20,17 @@
|
||||||
#ifndef _UI_UI_H
|
#ifndef _UI_UI_H
|
||||||
#define _UI_UI_H
|
#define _UI_UI_H
|
||||||
|
|
||||||
|
#include <ui/framebuffer.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct ui_context {
|
||||||
|
uint32_t *fb_addr;
|
||||||
|
struct fb_mode *fb_modes;
|
||||||
|
int total_modes;
|
||||||
|
int current_mode;
|
||||||
|
};
|
||||||
|
|
||||||
void ui_init();
|
void ui_init();
|
||||||
|
|
||||||
#endif /* _UI_UI_H */
|
#endif /* _UI_UI_H */
|
|
@ -52,7 +52,10 @@ UEFI_CFLAGS := $(CFLAGS) \
|
||||||
-DAXBOOT_UEFI=1 \
|
-DAXBOOT_UEFI=1 \
|
||||||
$(foreach d, $(INCLUDE_DIRS), -I$d) \
|
$(foreach d, $(INCLUDE_DIRS), -I$d) \
|
||||||
-target $(ARCH)-unknown-windows \
|
-target $(ARCH)-unknown-windows \
|
||||||
|
-std=c11 \
|
||||||
|
-flto \
|
||||||
-fshort-wchar \
|
-fshort-wchar \
|
||||||
|
-msoft-float \
|
||||||
-mno-red-zone \
|
-mno-red-zone \
|
||||||
-mno-stack-arg-probe
|
-mno-stack-arg-probe
|
||||||
|
|
||||||
|
@ -68,6 +71,7 @@ UEFI_LDFLAGS := $(LDFLAGS) \
|
||||||
-fuse-ld=lld-link \
|
-fuse-ld=lld-link \
|
||||||
-Wl,-subsystem:efi_application \
|
-Wl,-subsystem:efi_application \
|
||||||
-Wl,-entry:uefi_entry
|
-Wl,-entry:uefi_entry
|
||||||
|
|
||||||
COMMON_CFILES := $(shell find $(BOOT_ROOT)/common -name '*.c')
|
COMMON_CFILES := $(shell find $(BOOT_ROOT)/common -name '*.c')
|
||||||
COMMON_ARCH_CFILES := $(shell find $(BOOT_ROOT)/arch/$(ARCH)/common -name '*.c')
|
COMMON_ARCH_CFILES := $(shell find $(BOOT_ROOT)/arch/$(ARCH)/common -name '*.c')
|
||||||
COMMON_ARCH_ASFILES := $(shell find $(BOOT_ROOT)/arch/$(ARCH)/common -name '*.S')
|
COMMON_ARCH_ASFILES := $(shell find $(BOOT_ROOT)/arch/$(ARCH)/common -name '*.S')
|
||||||
|
|
53
boot/platform/uefi/driver.c
Normal file
53
boot/platform/uefi/driver.c
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*********************************************************************************/
|
||||||
|
/* Module Name: entry.c */
|
||||||
|
/* Project: AurixOS */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||||
|
/* */
|
||||||
|
/* This source is subject to the MIT License. */
|
||||||
|
/* See License.txt in the root of this repository. */
|
||||||
|
/* All other rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||||
|
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||||
|
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||||
|
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||||
|
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||||
|
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||||
|
/* SOFTWARE. */
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
// #include <driver.h>
|
||||||
|
#include <config/config.h>
|
||||||
|
#include <print.h>
|
||||||
|
|
||||||
|
#include <efi.h>
|
||||||
|
#include <efilib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
bool verify_secure_boot()
|
||||||
|
{
|
||||||
|
EFI_GUID var_guid = EFI_GLOBAL_VARIABLE;
|
||||||
|
EFI_UINT8 val = 0;
|
||||||
|
EFI_UINTN size = sizeof(val);
|
||||||
|
bool ret = 0;
|
||||||
|
|
||||||
|
if (!EFI_ERROR(gSystemTable->RuntimeServices->GetVariable(L"SecureBoot", &var_guid, NULL, &size, &val))) {
|
||||||
|
debug("verify_secure_boot(): Secure Boot Status: %u\n", val);
|
||||||
|
ret = (bool)val;
|
||||||
|
|
||||||
|
if (!EFI_ERROR(gSystemTable->RuntimeServices->GetVariable(L"SetupMode", &var_guid, NULL, &size, &val)) && val != 0) {
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return !ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_drivers()
|
||||||
|
{
|
||||||
|
if (!verify_secure_boot()) {
|
||||||
|
debug("load_drivers(): Secure boot is enabled! Won't load drivers...\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,33 +0,0 @@
|
||||||
###################################################################################
|
|
||||||
## Module Name: Makefile ##
|
|
||||||
## Project: AurixOS ##
|
|
||||||
## ##
|
|
||||||
## Copyright (c) 2024-2025 Jozef Nagy ##
|
|
||||||
## ##
|
|
||||||
## This source is subject to the MIT License. ##
|
|
||||||
## See License.txt in the root of this repository. ##
|
|
||||||
## All other rights reserved. ##
|
|
||||||
## ##
|
|
||||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ##
|
|
||||||
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ##
|
|
||||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ##
|
|
||||||
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ##
|
|
||||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ##
|
|
||||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ##
|
|
||||||
## SOFTWARE. ##
|
|
||||||
###################################################################################
|
|
||||||
|
|
||||||
SUBDIRS := $(wildcard */)
|
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all:
|
|
||||||
@for d in $(SUBDIRS); do \
|
|
||||||
printf ">>> Building $$d...\n"; \
|
|
||||||
$(MAKE) -C $$d; \
|
|
||||||
done
|
|
||||||
|
|
||||||
.PHONY: install
|
|
||||||
install: $(SUBDIRS)
|
|
||||||
@for d in $(SUBDIRS); do \
|
|
||||||
$(MAKE) -C $$d install; \
|
|
||||||
done
|
|
|
@ -1,11 +0,0 @@
|
||||||
Copyright 2018-2025 Rafael Rodrigues Machado, Jozef Nagy
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
@ -1,77 +0,0 @@
|
||||||
###################################################################################
|
|
||||||
## Module Name: Makefile ##
|
|
||||||
## Project: AurixOS ##
|
|
||||||
## ##
|
|
||||||
## Copyright (c) 2024-2025 Jozef Nagy ##
|
|
||||||
## ##
|
|
||||||
## This source is subject to the MIT License. ##
|
|
||||||
## See License.txt in the root of this repository. ##
|
|
||||||
## All other rights reserved. ##
|
|
||||||
## ##
|
|
||||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ##
|
|
||||||
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ##
|
|
||||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ##
|
|
||||||
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ##
|
|
||||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ##
|
|
||||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ##
|
|
||||||
## SOFTWARE. ##
|
|
||||||
###################################################################################
|
|
||||||
|
|
||||||
UEFI_DRIVER := $(BUILD_DIR)/boot/uefi/drivers/intel-hda.efi
|
|
||||||
|
|
||||||
INCLUDE_DIRS += $(BOOT_ROOT)/drivers/intel-hda \
|
|
||||||
$(BOOT_ROOT)/drivers/intel-hda/include \
|
|
||||||
$(BOOT_ROOT)/platform/uefi/libefi
|
|
||||||
|
|
||||||
UEFI_CC := clang
|
|
||||||
UEFI_LD := clang
|
|
||||||
|
|
||||||
UEFI_ASFLAGS := $(ASFLAGS) \
|
|
||||||
-DAXBOOT_UEFI=1 \
|
|
||||||
$(foreach d, $(INCLUDE_DIRS), -I$d)
|
|
||||||
|
|
||||||
UEFI_CFLAGS := $(CFLAGS) \
|
|
||||||
-DAXBOOT_UEFI=1 \
|
|
||||||
$(foreach d, $(INCLUDE_DIRS), -I$d) \
|
|
||||||
-target $(ARCH)-unknown-windows \
|
|
||||||
-fshort-wchar \
|
|
||||||
-mno-red-zone \
|
|
||||||
-mno-stack-arg-probe
|
|
||||||
|
|
||||||
ifneq (,$(filter $(ARCH),i686 x86_64))
|
|
||||||
UEFI_CFLAGS += -mno-80387 \
|
|
||||||
-mno-mmx \
|
|
||||||
-mno-sse \
|
|
||||||
-mno-sse2
|
|
||||||
endif
|
|
||||||
|
|
||||||
UEFI_LDFLAGS := $(LDFLAGS) \
|
|
||||||
-target $(ARCH)-unknown-windows \
|
|
||||||
-fuse-ld=lld-link \
|
|
||||||
-Wl,-subsystem:efi_boot_service_driver \
|
|
||||||
-Wl,-entry:InitHda
|
|
||||||
|
|
||||||
DRIVER_CFILES := $(shell find $(BOOT_ROOT)/drivers/intel-hda -name '*.c')
|
|
||||||
|
|
||||||
UEFI_OBJ := $(DRIVER_CFILES:$(BOOT_ROOT)/drivers/intel-hda/%.c=$(BUILD_DIR)/boot/uefi/drivers/intel-hda/%.c.o)
|
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all: $(UEFI_DRIVER)
|
|
||||||
|
|
||||||
.PHONY: install
|
|
||||||
install: $(UEFI_DRIVER)
|
|
||||||
@mkdir -p $(SYSROOT_DIR)/AxBoot/drivers
|
|
||||||
@printf " INSTALL\t/AxBoot/drivers/$(shell basename $(UEFI_DRIVER))\n"
|
|
||||||
@cp $(UEFI_DRIVER) $(SYSROOT_DIR)/AxBoot/drivers/
|
|
||||||
|
|
||||||
$(UEFI_DRIVER): $(UEFI_OBJ)
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
@printf " LD\t$(notdir $@)\n"
|
|
||||||
@$(UEFI_LD) $(UEFI_LDFLAGS) $^ -o $@
|
|
||||||
|
|
||||||
-include $(wildcard $(BUILD_DIR)/boot/*.d)
|
|
||||||
|
|
||||||
$(BUILD_DIR)/boot/uefi/drivers/intel-hda/%.c.o: $(BOOT_ROOT)/drivers/intel-hda/%.c
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
@printf " CC\t$(subst $(ROOT_DIR)/,,$<)\n"
|
|
||||||
@$(UEFI_CC) $(UEFI_CFLAGS) -c $< -o $@
|
|
|
@ -1,571 +0,0 @@
|
||||||
/*********************************************************************************/
|
|
||||||
/* Module Name: hda.c */
|
|
||||||
/* Project: AurixOS */
|
|
||||||
/* */
|
|
||||||
/* Copyright (c) 2018-2025, Rafael Rodrigues Machado, Jozef Nagy */
|
|
||||||
/* All rights reserved. */
|
|
||||||
/* This program and the accompanying materials are licensed and made available */
|
|
||||||
/* under the terms and conditions of the BSD License which accompanies */
|
|
||||||
/* this distribution. The full text of the license may be found at */
|
|
||||||
/* http://opensource.org/licenses/bsd-license. */
|
|
||||||
/* */
|
|
||||||
/* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, */
|
|
||||||
/* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. */
|
|
||||||
/*********************************************************************************/
|
|
||||||
|
|
||||||
#include <lib/string.h>
|
|
||||||
#include <mm/mman.h>
|
|
||||||
#include <efi.h>
|
|
||||||
#include <efilib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <print.h>
|
|
||||||
|
|
||||||
#include <hda.h>
|
|
||||||
#include <pciconf.h>
|
|
||||||
|
|
||||||
// Number of rows that are updated by the timer event for debug purposes
|
|
||||||
#define REFRESH_ROWS 9
|
|
||||||
#define Bar0 0
|
|
||||||
|
|
||||||
static uint64_t CorbCommandCount = 0;
|
|
||||||
|
|
||||||
PCI_HDA_REGION *PcieDeviceConfigSpace;
|
|
||||||
uint64_t *DmaPositionBuffer = NULL;
|
|
||||||
uint64_t *AddressBSL = NULL;
|
|
||||||
int16_t *AudioBuffer = NULL;
|
|
||||||
|
|
||||||
uint64_t CorbAddress;
|
|
||||||
void *CorbMapping = NULL;
|
|
||||||
uint8_t CorbLastAddedCommandIndex = 0;
|
|
||||||
|
|
||||||
uint64_t RirbAddress;
|
|
||||||
void *RirbMapping = NULL;
|
|
||||||
uint8_t RirbLastProcessedResponseIndex = 0;
|
|
||||||
|
|
||||||
EFI_STATUS AddCommandToCorb(uint32_t VerbToSend)
|
|
||||||
{
|
|
||||||
CorbLastAddedCommandIndex += 1;
|
|
||||||
if (CorbLastAddedCommandIndex >= 256) {
|
|
||||||
CorbLastAddedCommandIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
WritePciMemory(CorbAddress + (CorbLastAddedCommandIndex * sizeof(uint32_t)), (void *)&VerbToSend, 1, EfiPciWidthUint32);
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBWP, (void *)&CorbLastAddedCommandIndex, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
CorbCommandCount += 1;
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS ReadResponseFromRirb(uint64_t *VerbResponse)
|
|
||||||
{
|
|
||||||
RirbLastProcessedResponseIndex += 1;
|
|
||||||
if (RirbLastProcessedResponseIndex >= 256) {
|
|
||||||
RirbLastProcessedResponseIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ReadPciMemory(RirbAddress + (RirbLastProcessedResponseIndex * sizeof(uint64_t)), VerbResponse, 1, EfiPciWidthUint64);
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS InitHda()
|
|
||||||
{
|
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
|
||||||
Status = GetHdaPciIoHandler();
|
|
||||||
if (EFI_ERROR(Status))
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
Status = GetRootBridgeIoHandler();
|
|
||||||
if (EFI_ERROR(Status))
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS DisposeHdaLib()
|
|
||||||
{
|
|
||||||
// TODO: Release CORB and RIRB
|
|
||||||
// Close protocols
|
|
||||||
// Free Variables
|
|
||||||
// Close events
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS AllocateCORBBuffer(PCI_HDA_REGION* PcieDeviceConfigSpace)
|
|
||||||
{
|
|
||||||
uint8_t *CorbAddressPointer = NULL;
|
|
||||||
uint32_t ReadValue32 = 0;
|
|
||||||
uint32_t WriteValue = 0;
|
|
||||||
uint8_t WriteValue8 = 0;
|
|
||||||
|
|
||||||
SetupCommonBuffer(&CorbAddressPointer, 1024, &CorbMapping, 16);
|
|
||||||
CorbAddress = (uint64_t)CorbAddressPointer;
|
|
||||||
|
|
||||||
WriteValue = (CorbAddress & 0xFFFFFFFF);
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBLBASE,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
WriteValue = (CorbAddress >> 32);
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBUBASE,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
WriteValue = 0;
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBWP,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
WriteValue = 0x8000;
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBRP,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
ReadControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBRP,
|
|
||||||
(void *)&ReadValue32, 1, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
WriteValue = 0;
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBRP,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
WriteValue8 = 0x3;
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_CORBCTL,
|
|
||||||
(void *)&WriteValue8, 1, Bar0, EfiPciWidthUint8);
|
|
||||||
|
|
||||||
//debug("AllocateCORBBuffer(): CorbAddress=0x%llx\n", CorbAddress);
|
|
||||||
//debug("AllocateCORBBuffer(): CorbMapping=0x%llx\n", CorbMapping);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS AllocateRIRBBuffer(PCI_HDA_REGION* PcieDeviceConfigSpace)
|
|
||||||
{
|
|
||||||
uint8_t *RirbAddressPointer = NULL;
|
|
||||||
|
|
||||||
uint32_t WriteValue = 0;
|
|
||||||
uint8_t WriteValue8 = 0;
|
|
||||||
|
|
||||||
SetupCommonBuffer(&RirbAddressPointer, 2048, &RirbMapping, 16);
|
|
||||||
RirbAddress = (uint64_t)RirbAddressPointer;
|
|
||||||
|
|
||||||
WriteValue = (RirbAddress & 0xFFFFFFFF);
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_RIRBLBASE,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
WriteValue = (RirbAddress >> 32);
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_RIRBUBASE,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
WriteValue = 0;
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_RIRBWP,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
WriteValue8 = 0x2;
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_RIRBCTL,
|
|
||||||
(void *)&WriteValue8, 1, Bar0, EfiPciWidthUint8);
|
|
||||||
|
|
||||||
//debug("AllocateRIRBBuffer(): RirbAddress=0x%llx\n", RirbAddress);
|
|
||||||
//debug("AllocateRIRBBuffer(): RirbMapping=0x%llx\n", RirbMapping);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS FillCodecNode(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint32_t CurrentNodeId,
|
|
||||||
HDA_NODE_TYPE NodeType,
|
|
||||||
struct Node *CurrentNode)
|
|
||||||
{
|
|
||||||
uint32_t CurrentSubordinateNodeCount = 0;
|
|
||||||
struct Node TempNode;
|
|
||||||
|
|
||||||
TempNode.NodeId = CurrentNodeId;
|
|
||||||
TempNode.NodeType = NodeType;
|
|
||||||
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_VENDOR_ID, &TempNode.VendorId);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_REVISION_ID, &TempNode.RevisionId);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_SUBORDINATE_NODE_COUNT, &CurrentSubordinateNodeCount);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_FUNCTION_GROUP_TYPE, &TempNode.FunctionGroupType);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_AUDIO_FUNC_CAP, &TempNode.FuncCap);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_AUDIO_WIDGET_CAP, &TempNode.WidgetCap);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_SAMPLE_SIZE_RATE_CAP, &TempNode.SampleSizeRateCap);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_STREAM_FORMATS, &TempNode.StreamFormat);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_PIN_CAP, &TempNode.PinCap);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_INPUT_AMP_CAP, &TempNode.InputAmpCap);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_OUTPUT_AMP_CAP, &TempNode.OutputAmpCap);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_CONNECTION_LIST_LENGTH, &TempNode.ConnectionListLength);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_SUPPORTED_POWER_STATES, &TempNode.SupportedPowerStates);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_PROCESSING_CAP, &TempNode.ProcessingCap);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_GPIO_COUNT, &TempNode.GPIOCount);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_PARAMETER, HDA_PARAM_VOLUME_KNOB_CAP, &TempNode.VolKnobCap);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_POWER_STATE, 0, &TempNode.PowerState);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentNodeId, HDA_VRB_GET_CHANNEL_STREAM_ID, 0, &TempNode.ChannelStreamId);
|
|
||||||
|
|
||||||
TempNode.StartingChildNodeAddess = HDA_SUB_NODE_COUNT_START_NODE(CurrentSubordinateNodeCount);
|
|
||||||
TempNode.SubordinateNodeCount = HDA_SUB_NODE_COUNT_TOTAL_NODE(CurrentSubordinateNodeCount);
|
|
||||||
TempNode.WidgetType = HDA_WIDGET_TYPE(TempNode.WidgetCap);
|
|
||||||
TempNode.RightGain = GetAmplifierGain(PcieDeviceConfigSpace, TempNode.NodeId, true, false);
|
|
||||||
TempNode.LeftGain = GetAmplifierGain(PcieDeviceConfigSpace, TempNode.NodeId, true, true);
|
|
||||||
|
|
||||||
memcpy(CurrentNode, &TempNode, sizeof(struct Node));
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS GetNodeById(struct Node *RootNode,
|
|
||||||
uint32_t NodeIdToSearch,
|
|
||||||
struct Node *NodeDetected)
|
|
||||||
{
|
|
||||||
struct Node *CurrentFunctionGroupNode = NULL;
|
|
||||||
struct Node *CurrentWidgetNode = NULL;
|
|
||||||
|
|
||||||
uint32_t CurrentFunctionGroupId = 0;
|
|
||||||
uint32_t CurrentFgArrayIndexer = 0;
|
|
||||||
|
|
||||||
uint32_t CurrentWidgetId = 0;
|
|
||||||
uint32_t CurrentWidgetArrayIndexer = 0;
|
|
||||||
|
|
||||||
for (CurrentFunctionGroupId = RootNode->StartingChildNodeAddess; CurrentFunctionGroupId < RootNode->StartingChildNodeAddess + RootNode->SubordinateNodeCount; CurrentFunctionGroupId++, CurrentFgArrayIndexer++) {
|
|
||||||
CurrentFunctionGroupNode = &(RootNode->ChildNodes[CurrentFgArrayIndexer]);
|
|
||||||
|
|
||||||
if (CurrentFunctionGroupNode->NodeId == NodeIdToSearch) {
|
|
||||||
memcpy(NodeDetected, CurrentFunctionGroupNode, sizeof(struct Node));
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentWidgetArrayIndexer = 0;
|
|
||||||
for (CurrentWidgetId = CurrentFunctionGroupNode->StartingChildNodeAddess; CurrentWidgetId < CurrentFunctionGroupNode->StartingChildNodeAddess + CurrentFunctionGroupNode->SubordinateNodeCount - 1; CurrentWidgetId++, CurrentWidgetArrayIndexer++) {
|
|
||||||
CurrentWidgetNode = &(CurrentFunctionGroupNode->ChildNodes[CurrentWidgetArrayIndexer]);
|
|
||||||
|
|
||||||
if (CurrentWidgetNode->NodeId == NodeIdToSearch) {
|
|
||||||
memcpy(NodeDetected, CurrentWidgetNode,sizeof(struct Node));
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS GetCodecTree(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
struct Node *RootNode)
|
|
||||||
{
|
|
||||||
struct Node *CurrentFunctionGroupNode = NULL;
|
|
||||||
struct Node *CurrentWidgetNode = NULL;
|
|
||||||
|
|
||||||
uint32_t CurrentFunctionGroupId = 0;
|
|
||||||
uint32_t CurrentFgArrayIndexer = 0;
|
|
||||||
|
|
||||||
uint32_t CurrentWidgetId = 0;
|
|
||||||
uint32_t CurrentWidgetArrayIndexer = 0;
|
|
||||||
|
|
||||||
FillCodecNode(PcieDeviceConfigSpace, 0, HDA_NODE_ROOT, RootNode);
|
|
||||||
RootNode->ChildNodes = mem_alloc(sizeof(struct Node) * (RootNode->SubordinateNodeCount - RootNode->StartingChildNodeAddess));
|
|
||||||
memset(RootNode->ChildNodes, 0, sizeof(struct Node) * (RootNode->SubordinateNodeCount - RootNode->StartingChildNodeAddess));
|
|
||||||
|
|
||||||
for (CurrentFunctionGroupId = RootNode->StartingChildNodeAddess; CurrentFunctionGroupId < RootNode->StartingChildNodeAddess + RootNode->SubordinateNodeCount; CurrentFunctionGroupId++, CurrentFgArrayIndexer++) {
|
|
||||||
CurrentFunctionGroupNode = &(RootNode->ChildNodes[CurrentFgArrayIndexer]);
|
|
||||||
FillCodecNode(PcieDeviceConfigSpace, CurrentFunctionGroupId, HDA_NODE_FUNCTION_GROUP, CurrentFunctionGroupNode);
|
|
||||||
CurrentFunctionGroupNode->ChildNodes = mem_alloc(sizeof(struct Node) * CurrentFunctionGroupNode->StartingChildNodeAddess + CurrentFunctionGroupNode->SubordinateNodeCount);
|
|
||||||
memset(CurrentFunctionGroupNode->ChildNodes, 0, sizeof(struct Node) * CurrentFunctionGroupNode->StartingChildNodeAddess + CurrentFunctionGroupNode->SubordinateNodeCount);
|
|
||||||
|
|
||||||
CurrentWidgetArrayIndexer = 0;
|
|
||||||
for (CurrentWidgetId = CurrentFunctionGroupNode->StartingChildNodeAddess; CurrentWidgetId < CurrentFunctionGroupNode->StartingChildNodeAddess + CurrentFunctionGroupNode->SubordinateNodeCount - 1; CurrentWidgetId++, CurrentWidgetArrayIndexer++) {
|
|
||||||
CurrentWidgetNode = &(CurrentFunctionGroupNode->ChildNodes[CurrentWidgetArrayIndexer]);
|
|
||||||
FillCodecNode(PcieDeviceConfigSpace, CurrentWidgetId, HDA_NODE_WIDGET, CurrentWidgetNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS ReleaseCodecTree(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
struct Node *RootNode)
|
|
||||||
{
|
|
||||||
struct Node *CurrentFunctionGroupNode = NULL;
|
|
||||||
uint32_t CurrentFunctionGroupId = 0;
|
|
||||||
uint32_t CurrentFgArrayIndexer = 0;
|
|
||||||
|
|
||||||
for (CurrentFunctionGroupId = RootNode->StartingChildNodeAddess; CurrentFunctionGroupId < RootNode->StartingChildNodeAddess + RootNode->SubordinateNodeCount - 1; CurrentFunctionGroupId++, CurrentFgArrayIndexer++) {
|
|
||||||
CurrentFunctionGroupNode = &(RootNode->ChildNodes[CurrentFgArrayIndexer]);
|
|
||||||
mem_free(CurrentFunctionGroupNode->ChildNodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
mem_free(RootNode->ChildNodes);
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS GetCodecData8BitPayload(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint8_t CodecAddress, uint8_t NodeId,
|
|
||||||
HDA_VERB Verb, uint8_t VerbPayload,
|
|
||||||
uint32_t *Response)
|
|
||||||
{
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS GetCodecData8BitPayloadCorbRirb(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint8_t CodecAddress, uint8_t NodeId,
|
|
||||||
HDA_VERB Verb, uint8_t VerbPayload,
|
|
||||||
uint32_t *Response)
|
|
||||||
{
|
|
||||||
HDA_COMMAND_FIELD_8BIT_PAYLOAD Command;
|
|
||||||
HDA_RESPONSE_FIELD *RawResponse;
|
|
||||||
|
|
||||||
uint32_t VerbToSend = 0;
|
|
||||||
uint64_t TempResponse = 0;
|
|
||||||
|
|
||||||
Command.CAd = CodecAddress;
|
|
||||||
Command.NID = NodeId;
|
|
||||||
Command.VerbIdent = Verb;
|
|
||||||
Command.VerbPayload = VerbPayload;
|
|
||||||
|
|
||||||
memcpy(&VerbToSend, &Command, sizeof(uint32_t));
|
|
||||||
AddCommandToCorb(VerbToSend);
|
|
||||||
|
|
||||||
gBootServices->Stall(200);
|
|
||||||
|
|
||||||
ReadResponseFromRirb(&TempResponse);
|
|
||||||
|
|
||||||
RawResponse = (HDA_RESPONSE_FIELD *)&TempResponse;
|
|
||||||
memcpy(Response, &RawResponse->Response, sizeof(uint32_t));
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS GetCodecData16BitPayloadCorbRirb(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint8_t CodecAddress, uint8_t NodeId,
|
|
||||||
HDA_VERB Verb, uint16_t VerbPayload,
|
|
||||||
uint32_t *Response)
|
|
||||||
{
|
|
||||||
HDA_COMMAND_FIELD_16BIT_PAYLOAD Command;
|
|
||||||
HDA_RESPONSE_FIELD *RawResponse;
|
|
||||||
|
|
||||||
uint32_t VerbToSend = 0;
|
|
||||||
uint64_t TempResponse = 0;
|
|
||||||
|
|
||||||
Command.CAd = CodecAddress;
|
|
||||||
Command.NID = NodeId;
|
|
||||||
Command.VerbIdent = Verb;
|
|
||||||
Command.VerbPayload = VerbPayload;
|
|
||||||
|
|
||||||
memcpy(&VerbToSend, &Command, sizeof(uint32_t));
|
|
||||||
AddCommandToCorb(VerbToSend);
|
|
||||||
|
|
||||||
gBootServices->Stall(200);
|
|
||||||
|
|
||||||
ReadResponseFromRirb(&TempResponse);
|
|
||||||
|
|
||||||
RawResponse = (HDA_RESPONSE_FIELD *)&TempResponse;
|
|
||||||
memcpy(Response, &RawResponse->Response, sizeof(uint32_t));
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
EFI_STATUS SendCommandToAllWidgets8BitPayload (
|
|
||||||
PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
HDA_VERB Verb, uint8_t VerbPayload)
|
|
||||||
{
|
|
||||||
struct Node RootNode;
|
|
||||||
uint32_t Response;
|
|
||||||
|
|
||||||
GetCodecTree(PcieDeviceConfigSpace, &RootNode);
|
|
||||||
|
|
||||||
struct Node *CurrentFunctionGroupNode = NULL;
|
|
||||||
struct Node *CurrentWidgetNode = NULL;
|
|
||||||
|
|
||||||
uint32_t CurrentFunctionGroupId = 0;
|
|
||||||
uint32_t CurrentFgArrayIndexer = 0;
|
|
||||||
|
|
||||||
uint32_t CurrentWidgetId = 0;
|
|
||||||
uint32_t CurrentWidgetArrayIndexer = 0;
|
|
||||||
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, 0, Verb, VerbPayload, &Response);
|
|
||||||
|
|
||||||
debug("Verb 0x%llx with payload 0x%llx sent to node 0x0\n", Verb, VerbPayload);
|
|
||||||
for (CurrentFunctionGroupId = RootNode.StartingChildNodeAddess; CurrentFunctionGroupId < RootNode.StartingChildNodeAddess + RootNode.SubordinateNodeCount; CurrentFunctionGroupId++, CurrentFgArrayIndexer++) {
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentFunctionGroupId, Verb, VerbPayload, &Response);
|
|
||||||
CurrentFunctionGroupNode = &(RootNode.ChildNodes[CurrentFgArrayIndexer]);
|
|
||||||
CurrentWidgetArrayIndexer = 0;
|
|
||||||
|
|
||||||
for (CurrentWidgetId = CurrentFunctionGroupNode->StartingChildNodeAddess; CurrentWidgetId < CurrentFunctionGroupNode->StartingChildNodeAddess + CurrentFunctionGroupNode->SubordinateNodeCount - 1; CurrentWidgetId++, CurrentWidgetArrayIndexer++) {
|
|
||||||
CurrentWidgetNode = &(CurrentFunctionGroupNode->ChildNodes[CurrentWidgetArrayIndexer]);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentWidgetId, Verb, VerbPayload, &Response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseCodecTree(PcieDeviceConfigSpace, &RootNode);
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS SendCommandToAllWidgets16BitPayload (
|
|
||||||
PCI_HDA_REGION* PcieDeviceConfigSpace,
|
|
||||||
HDA_VERB Verb, uint16_t VerbPayload)
|
|
||||||
{
|
|
||||||
struct Node RootNode;
|
|
||||||
uint32_t Response;
|
|
||||||
|
|
||||||
GetCodecTree(PcieDeviceConfigSpace, &RootNode);
|
|
||||||
|
|
||||||
struct Node *CurrentFunctionGroupNode = NULL;
|
|
||||||
struct Node *CurrentWidgetNode = NULL;
|
|
||||||
|
|
||||||
uint32_t CurrentFunctionGroupId = 0;
|
|
||||||
uint32_t CurrentFgArrayIndexer = 0;
|
|
||||||
|
|
||||||
uint32_t CurrentWidgetId = 0;
|
|
||||||
uint32_t CurrentWidgetArrayIndexer = 0;
|
|
||||||
|
|
||||||
GetCodecData16BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, 0, Verb, VerbPayload, &Response);
|
|
||||||
|
|
||||||
for (CurrentFunctionGroupId = RootNode.StartingChildNodeAddess; CurrentFunctionGroupId < RootNode.StartingChildNodeAddess + RootNode.SubordinateNodeCount; CurrentFunctionGroupId++, CurrentFgArrayIndexer++) {
|
|
||||||
GetCodecData16BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentFunctionGroupId, Verb, VerbPayload, &Response);
|
|
||||||
CurrentFunctionGroupNode = &(RootNode.ChildNodes[CurrentFgArrayIndexer]);
|
|
||||||
CurrentWidgetArrayIndexer = 0;
|
|
||||||
|
|
||||||
for (CurrentWidgetId = CurrentFunctionGroupNode->StartingChildNodeAddess; CurrentWidgetId < CurrentFunctionGroupNode->StartingChildNodeAddess + CurrentFunctionGroupNode->SubordinateNodeCount - 1; CurrentWidgetId++, CurrentWidgetArrayIndexer++) {
|
|
||||||
CurrentWidgetNode = &(CurrentFunctionGroupNode->ChildNodes[CurrentWidgetArrayIndexer]);
|
|
||||||
GetCodecData16BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, CurrentWidgetId, Verb, VerbPayload, &Response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseCodecTree(PcieDeviceConfigSpace, &RootNode);
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS GetCodecData16BitPayload(PCI_HDA_REGION* PcieDeviceConfigSpace,
|
|
||||||
uint8_t CodecAddress, uint8_t NodeId,
|
|
||||||
HDA_VERB Verb, uint16_t VerbPayload,
|
|
||||||
uint32_t *Response)
|
|
||||||
{
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t GetAmplifierGain(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint8_t NodeId, bool InputOutput,
|
|
||||||
bool LeftRight)
|
|
||||||
{
|
|
||||||
uint32_t Response = 0;
|
|
||||||
uint16_t PayloadToSend = 0;
|
|
||||||
|
|
||||||
PayloadToSend = NodeId;
|
|
||||||
PayloadToSend |= (InputOutput << 15);
|
|
||||||
PayloadToSend |= (LeftRight << 13);
|
|
||||||
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0x0, NodeId, HDA_VRB_GET_AMPLIFIER_GAIN_MUTE, 0x0, &Response);
|
|
||||||
return Response;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS DisablePcieInterrupts(PCI_HDA_REGION *PcieDeviceConfigSpace)
|
|
||||||
{
|
|
||||||
uint16_t CommandRegister = 0;
|
|
||||||
|
|
||||||
ReadControllerPcieConfiguration(PcieDeviceConfigSpace, HDA_OFFSET_PCIE_PCICMD, &CommandRegister, 1, EfiPciWidthUint16);
|
|
||||||
CommandRegister += (1 << 10);
|
|
||||||
WriteControllerPcieConfiguration(PcieDeviceConfigSpace, HDA_OFFSET_PCIE_PCICMD, (void *)&CommandRegister, 1, EfiPciWidthUint16);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS EnablePcieNoSnoop(PCI_HDA_REGION *PcieDeviceConfigSpace)
|
|
||||||
{
|
|
||||||
uint16_t DeviceControlRegister = 0;
|
|
||||||
|
|
||||||
ReadControllerPcieConfiguration(PcieDeviceConfigSpace, HDA_OFFSET_PCIE_DEVCTL, (void *)&DeviceControlRegister, 1, EfiPciWidthUint16);
|
|
||||||
DeviceControlRegister += (1 << 11);
|
|
||||||
WriteControllerPcieConfiguration(PcieDeviceConfigSpace, HDA_OFFSET_PCIE_DEVCTL, (void *)&DeviceControlRegister, 1, EfiPciWidthUint16);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS AddDescriptorListEntryOss0(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
HDA_CONTROLLER_REGISTER_SET *ControllerRegisterSet,
|
|
||||||
uint64_t DataAddress,
|
|
||||||
uint32_t DataLength,
|
|
||||||
uint8_t BdlEntryIndex,
|
|
||||||
uint32_t SdxLastValidIndex)
|
|
||||||
{
|
|
||||||
EFI_UINT64 BdlAddress;
|
|
||||||
EFI_UINT32 BdlLower;
|
|
||||||
EFI_UINT64 BdlUpper;
|
|
||||||
|
|
||||||
HDA_BUFFER_DESCRIPTOR_LIST *DescriptorList = NULL;
|
|
||||||
|
|
||||||
ReadControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(0, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXBDPL,
|
|
||||||
(void *)&BdlLower, 1, EfiPciWidthUint32);
|
|
||||||
ReadControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(0, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXBDPU,
|
|
||||||
(void *)&BdlUpper, 1, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
BdlAddress = BdlLower | (BdlUpper << 32);
|
|
||||||
|
|
||||||
DescriptorList = (HDA_BUFFER_DESCRIPTOR_LIST *)BdlAddress;
|
|
||||||
DescriptorList->BDLEntry[BdlEntryIndex].Address = DataAddress;
|
|
||||||
DescriptorList->BDLEntry[BdlEntryIndex].Length = DataLength;
|
|
||||||
|
|
||||||
// TODO: Enable this after Corb/Rirb start to process unsolicited responses
|
|
||||||
DescriptorList->BDLEntry[BdlEntryIndex].IntrptOnComp = 1;
|
|
||||||
|
|
||||||
return WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(0, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXLVI,
|
|
||||||
(void *)&SdxLastValidIndex, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS AllocateStreamsPages(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
HDA_CONTROLLER_REGISTER_SET *ControllerRegisterSet)
|
|
||||||
{
|
|
||||||
uint8_t *BdlAddressPointer = NULL;
|
|
||||||
void *BdlMapping = NULL;
|
|
||||||
uint64_t BdlAddress;
|
|
||||||
|
|
||||||
// DMAPositionBuffer
|
|
||||||
uint8_t *DmaAddressPointer = NULL;
|
|
||||||
void *DmaMapping = NULL;
|
|
||||||
uint64_t DmaAddress;
|
|
||||||
|
|
||||||
uint32_t WriteValue = 0;
|
|
||||||
|
|
||||||
uint64_t IssCount = (ControllerRegisterSet->GCAP >> 8) & 0xF;
|
|
||||||
uint64_t OssCount = (ControllerRegisterSet->GCAP >> 12) & 0xF;
|
|
||||||
uint64_t BssCount = (ControllerRegisterSet->GCAP >> 3) & 0x1F;
|
|
||||||
uint64_t Count = 0;
|
|
||||||
|
|
||||||
for (Count = 0; Count < IssCount; Count++) {
|
|
||||||
SetupCommonBuffer(&BdlAddressPointer, sizeof(HDA_BUFFER_DESCRIPTOR_LIST), &BdlMapping, 16);
|
|
||||||
|
|
||||||
BdlAddress = (uint64_t)BdlAddressPointer;
|
|
||||||
WriteValue = (BdlAddress & 0xFFFFFFFF);
|
|
||||||
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_ISSN_OFFSET(Count) + HDA_RELATIVE_OFFSET_SDXBDPL,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
WriteValue = (BdlAddress >> 32);
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_ISSN_OFFSET(Count) + HDA_RELATIVE_OFFSET_SDXBDPU,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Count = 0; Count < OssCount; Count++) {
|
|
||||||
SetupCommonBuffer(&BdlAddressPointer, sizeof(HDA_BUFFER_DESCRIPTOR_LIST), &BdlMapping, 16);
|
|
||||||
|
|
||||||
BdlAddress = (uint64_t)BdlAddressPointer;
|
|
||||||
WriteValue = (BdlAddress & 0xFFFFFFFF);
|
|
||||||
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(Count, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXBDPL,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
WriteValue = (BdlAddress >> 32);
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(Count, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXBDPU,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Count = 0; Count < BssCount; Count++) {
|
|
||||||
SetupCommonBuffer(&BdlAddressPointer, sizeof(HDA_BUFFER_DESCRIPTOR_LIST), &BdlMapping, 16);
|
|
||||||
|
|
||||||
BdlAddress = (uint64_t)BdlAddressPointer;
|
|
||||||
WriteValue = (BdlAddress & 0xFFFFFFFF);
|
|
||||||
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_BSSN_OFFSET(Count, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXBDPL,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
WriteValue = (BdlAddress >> 32);
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_BSSN_OFFSET(Count, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXBDPU,
|
|
||||||
(void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetupCommonBuffer(&DmaAddressPointer, (IssCount + OssCount + BssCount) * sizeof(uint64_t), &DmaMapping, 16);
|
|
||||||
DmaAddress = (uint64_t)DmaAddressPointer;
|
|
||||||
|
|
||||||
WriteValue = (DmaAddress & 0xFFFFFFFF);
|
|
||||||
WriteValue |= 0x01;
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_DPIBLBASE, (void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
WriteValue = (DmaAddress >> 32);
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_DPIBUBASE, (void *)&WriteValue, 1, Bar0, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
|
@ -1,688 +0,0 @@
|
||||||
/*********************************************************************************/
|
|
||||||
/* Module Name: hda.h */
|
|
||||||
/* Project: AurixOS */
|
|
||||||
/* */
|
|
||||||
/* Copyright (c) 2018-2025, Rafael Rodrigues Machado, Jozef Nagy */
|
|
||||||
/* All rights reserved. */
|
|
||||||
/* This program and the accompanying materials are licensed and made available */
|
|
||||||
/* under the terms and conditions of the BSD License which accompanies */
|
|
||||||
/* this distribution. The full text of the license may be found at */
|
|
||||||
/* http://opensource.org/licenses/bsd-license. */
|
|
||||||
/* */
|
|
||||||
/* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, */
|
|
||||||
/* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. */
|
|
||||||
/*********************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _HDA_HDA_H
|
|
||||||
#define _HDA_HDA_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
// Intel HDA Controller location
|
|
||||||
#define HDA_BUS 0
|
|
||||||
#define HDA_DEV 27
|
|
||||||
#define HDA_FUNC 0
|
|
||||||
|
|
||||||
// HDA Spec page 57
|
|
||||||
#define HDA_BUFFER_DESC_LIST_MAX_ENTRIES 256
|
|
||||||
|
|
||||||
// IO-Controller_Hub-7-hd-audio-ac97 manual, page 13
|
|
||||||
typedef struct {
|
|
||||||
uint16_t VID;
|
|
||||||
uint16_t DID;
|
|
||||||
uint16_t PCICMD;
|
|
||||||
uint16_t PCISTS;
|
|
||||||
uint8_t RID;
|
|
||||||
uint8_t PI;
|
|
||||||
uint8_t SC;
|
|
||||||
uint8_t BCC;
|
|
||||||
uint8_t CLS;
|
|
||||||
uint8_t LT;
|
|
||||||
uint8_t HEADTYP;
|
|
||||||
uint8_t RES0;
|
|
||||||
uint32_t HDBARL;
|
|
||||||
uint32_t HDBARU;
|
|
||||||
uint8_t RESV1[20];
|
|
||||||
uint16_t SVID;
|
|
||||||
uint16_t SID;
|
|
||||||
uint8_t RESV2[4];
|
|
||||||
uint8_t CAPPTR;
|
|
||||||
uint8_t RESV3[7];
|
|
||||||
uint8_t INTLN;
|
|
||||||
uint8_t INTPN;
|
|
||||||
uint8_t RESV4[2];
|
|
||||||
uint8_t HDCTL;
|
|
||||||
uint8_t RESV5[3];
|
|
||||||
uint8_t TCSEL;
|
|
||||||
uint8_t RESV6[8];
|
|
||||||
uint8_t DCKSTS;
|
|
||||||
uint8_t RESV7[2];
|
|
||||||
uint16_t PID;
|
|
||||||
uint16_t PC;
|
|
||||||
uint32_t PCS;
|
|
||||||
uint8_t RESV8[8];
|
|
||||||
uint16_t MID;
|
|
||||||
uint16_t MMC;
|
|
||||||
uint32_t MMLA;
|
|
||||||
uint32_t MMUA;
|
|
||||||
uint16_t MMD;
|
|
||||||
uint8_t RESV9[2];
|
|
||||||
uint16_t PXID;
|
|
||||||
uint16_t PXC;
|
|
||||||
uint32_t DEVCAP;
|
|
||||||
uint16_t DEVCTL;
|
|
||||||
uint16_t DEVS;
|
|
||||||
uint8_t RESV10[132];
|
|
||||||
uint32_t VCCAP;
|
|
||||||
uint32_t PVCCAP1;
|
|
||||||
uint32_t PVCCAP2;
|
|
||||||
uint16_t PVCCTL;
|
|
||||||
uint16_t PVCSTS;
|
|
||||||
uint32_t VC0CAP;
|
|
||||||
uint32_t VC0CTL;
|
|
||||||
uint8_t RESV11[2];
|
|
||||||
uint16_t VC0STS;
|
|
||||||
uint32_t VciCAP;
|
|
||||||
uint32_t VciCTL;
|
|
||||||
uint8_t RESV12[2];
|
|
||||||
uint16_t VciSTS;
|
|
||||||
uint8_t RESV13[8];
|
|
||||||
uint32_t RCCAP;
|
|
||||||
uint32_t ESD;
|
|
||||||
uint8_t RESV14[8];
|
|
||||||
uint32_t L1DESC;
|
|
||||||
uint8_t RESV15[4];
|
|
||||||
uint32_t L1ADDL;
|
|
||||||
uint32_t L1ADDU;
|
|
||||||
} PCI_HDA_REGION;
|
|
||||||
|
|
||||||
// Register offsets defined at HDA PCIe config space
|
|
||||||
#define HDA_OFFSET_PCIE_VID 0x0
|
|
||||||
#define HDA_OFFSET_PCIE_DID 0x2
|
|
||||||
#define HDA_OFFSET_PCIE_PCICMD 0x4
|
|
||||||
#define HDA_OFFSET_PCIE_PCISTS 0x6
|
|
||||||
#define HDA_OFFSET_PCIE_RID 0x8
|
|
||||||
#define HDA_OFFSET_PCIE_PI 0x9
|
|
||||||
#define HDA_OFFSET_PCIE_SCC 0xA
|
|
||||||
#define HDA_OFFSET_PCIE_BCC 0xB
|
|
||||||
#define HDA_OFFSET_PCIE_CLS 0xC
|
|
||||||
#define HDA_OFFSET_PCIE_LT 0xD
|
|
||||||
#define HDA_OFFSET_PCIE_HEADTYP 0xE
|
|
||||||
#define HDA_OFFSET_PCIE_HDBARL 0x10
|
|
||||||
#define HDA_OFFSET_PCIE_HDBARU 0x14
|
|
||||||
#define HDA_OFFSET_PCIE_SVID 0x2C
|
|
||||||
#define HDA_OFFSET_PCIE_SID 0x2E
|
|
||||||
#define HDA_OFFSET_PCIE_CAPPTR 0x34
|
|
||||||
#define HDA_OFFSET_PCIE_INTLN 0x3C
|
|
||||||
#define HDA_OFFSET_PCIE_INTPN 0x3D
|
|
||||||
#define HDA_OFFSET_PCIE_HDCTL 0x40
|
|
||||||
#define HDA_OFFSET_PCIE_TCSEL 0x44
|
|
||||||
#define HDA_OFFSET_PCIE_DCKSTS 0x4D
|
|
||||||
#define HDA_OFFSET_PCIE_PID 0x50
|
|
||||||
#define HDA_OFFSET_PCIE_PC 0x52
|
|
||||||
#define HDA_OFFSET_PCIE_PCS 0x54
|
|
||||||
#define HDA_OFFSET_PCIE_MID 0x60
|
|
||||||
#define HDA_OFFSET_PCIE_MMC 0x62
|
|
||||||
#define HDA_OFFSET_PCIE_MMLA 0x64
|
|
||||||
#define HDA_OFFSET_PCIE_MMUA 0x68
|
|
||||||
#define HDA_OFFSET_PCIE_MMD 0x6C
|
|
||||||
#define HDA_OFFSET_PCIE_PXID 0x70
|
|
||||||
#define HDA_OFFSET_PCIE_PXC 0x72
|
|
||||||
#define HDA_OFFSET_PCIE_DEVCAP 0x74
|
|
||||||
#define HDA_OFFSET_PCIE_DEVCTL 0x78
|
|
||||||
#define HDA_OFFSET_PCIE_DEVS 0x7A
|
|
||||||
#define HDA_OFFSET_PCIE_VCCAP 0x100
|
|
||||||
#define HDA_OFFSET_PCIE_PVCCAP1 0x104
|
|
||||||
#define HDA_OFFSET_PCIE_PVCCAP2 0x108
|
|
||||||
#define HDA_OFFSET_PCIE_PVCCTL 0x10C
|
|
||||||
#define HDA_OFFSET_PCIE_PVCSTS 0x10E
|
|
||||||
#define HDA_OFFSET_PCIE_VC0CAP 0x110
|
|
||||||
#define HDA_OFFSET_PCIE_VC0CTL 0x114
|
|
||||||
#define HDA_OFFSET_PCIE_VC0STS 0x11A
|
|
||||||
#define HDA_OFFSET_PCIE_VciCAP 0x11C
|
|
||||||
#define HDA_OFFSET_PCIE_VciCTL 0x120
|
|
||||||
#define HDA_OFFSET_PCIE_VciSTS 0x126
|
|
||||||
#define HDA_OFFSET_PCIE_RCCAP 0x130
|
|
||||||
#define HDA_OFFSET_PCIE_ESD 0x134
|
|
||||||
#define HDA_OFFSET_PCIE_L1DESC 0x140
|
|
||||||
#define HDA_OFFSET_PCIE_L1ADDL 0x148
|
|
||||||
#define HDA_OFFSET_PCIE_L1ADDU 0x14C
|
|
||||||
|
|
||||||
/* Offsets of the registers defined at HDA
|
|
||||||
* compatible controllers.
|
|
||||||
* Details can be found at the page 27 of the
|
|
||||||
* HDA Specification Rev 1.0a
|
|
||||||
*/
|
|
||||||
// Register offsets defined at HDA compatible controllers
|
|
||||||
#define HDA_OFFSET_GCAP 0x0
|
|
||||||
#define HDA_OFFSET_VMIN 0x2
|
|
||||||
#define HDA_OFFSET_VMAJ 0x3
|
|
||||||
#define HDA_OFFSET_OUTPAY 0x4
|
|
||||||
#define HDA_OFFSET_INPAY 0x6
|
|
||||||
#define HDA_OFFSET_GCTL 0x8
|
|
||||||
#define HDA_OFFSET_WAKEEN 0x0C
|
|
||||||
#define HDA_OFFSET_WAKESTS 0x0E
|
|
||||||
#define HDA_OFFSET_GSTS 0x10
|
|
||||||
#define HDA_OFFSET_Rsvd 0x12
|
|
||||||
#define HDA_OFFSET_OUTSTRMPAY 0x18
|
|
||||||
#define HDA_OFFSET_INSTRMPAY 0x1A
|
|
||||||
#define HDA_OFFSET_INTCTL 0x20
|
|
||||||
#define HDA_OFFSET_INTSTS 0x24
|
|
||||||
#define HDA_OFFSET_WALCLK 0x30
|
|
||||||
#define HDA_OFFSET_SSYNC 0x38
|
|
||||||
#define HDA_OFFSET_CORBLBASE 0x40
|
|
||||||
#define HDA_OFFSET_CORBUBASE 0x44
|
|
||||||
#define HDA_OFFSET_CORBWP 0x48
|
|
||||||
#define HDA_OFFSET_CORBRP 0x4A
|
|
||||||
#define HDA_OFFSET_CORBCTL 0x4C
|
|
||||||
#define HDA_OFFSET_CORBSTS 0x4D
|
|
||||||
#define HDA_OFFSET_CORBSIZE 0x4E
|
|
||||||
#define HDA_OFFSET_RIRBLBASE 0x50
|
|
||||||
#define HDA_OFFSET_RIRBUBASE 0x54
|
|
||||||
#define HDA_OFFSET_RIRBWP 0x58
|
|
||||||
#define HDA_OFFSET_RINTCNT 0x5A
|
|
||||||
#define HDA_OFFSET_RIRBCTL 0x5C
|
|
||||||
#define HDA_OFFSET_RIRBSTS 0x5D
|
|
||||||
#define HDA_OFFSET_RIRBSIZE 0x5E
|
|
||||||
#define HDA_OFFSET_ICOI 0x60
|
|
||||||
#define HDA_OFFSET_ICII 0x64
|
|
||||||
#define HDA_OFFSET_ICIS 0x68
|
|
||||||
#define HDA_OFFSET_DPIBLBASE 0x70
|
|
||||||
#define HDA_OFFSET_DPIBUBASE 0x74
|
|
||||||
|
|
||||||
#define HDA_OFFSET_SD0CTL 0x80
|
|
||||||
#define HDA_OFFSET_SD0STS 0x83
|
|
||||||
#define HDA_OFFSET_SD0LPIB 0x84
|
|
||||||
#define HDA_OFFSET_SD0CBL 0x88
|
|
||||||
#define HDA_OFFSET_SD0LVI 0x8C
|
|
||||||
#define HDA_OFFSET_SD0FIFOS 0x90
|
|
||||||
#define HDA_OFFSET_SD0FMT 0x92
|
|
||||||
#define HDA_OFFSET_SD0BDPL 0x98
|
|
||||||
#define HDA_OFFSET_SD0BDPU 0x9C
|
|
||||||
|
|
||||||
// HDA Spec 1.0a page 27
|
|
||||||
#define HDA_RELATIVE_OFFSET_SDXCTL 0
|
|
||||||
#define HDA_RELATIVE_OFFSET_SDXSTS 0x3
|
|
||||||
#define HDA_RELATIVE_OFFSET_SDXLPIB 0x4
|
|
||||||
#define HDA_RELATIVE_OFFSET_SDXCBL 0x8
|
|
||||||
#define HDA_RELATIVE_OFFSET_SDXLVI 0xC
|
|
||||||
#define HDA_RELATIVE_OFFSET_SDXFIFOS 0x10
|
|
||||||
#define HDA_RELATIVE_OFFSET_SDXFMT 0x12
|
|
||||||
#define HDA_RELATIVE_OFFSET_SDXBDPL 0x18
|
|
||||||
#define HDA_RELATIVE_OFFSET_SDXBDPU 0x1C
|
|
||||||
|
|
||||||
// Extract OSS count from controller's global capabilities register
|
|
||||||
#define HDA_OSS_COUNT(GCAP) ((GCAP >> 12) & 0xF)
|
|
||||||
|
|
||||||
// Extract ISS count from controller's global capabilities register
|
|
||||||
#define HDA_ISS_COUNT(GCAP) ((GCAP >> 8) & 0xF)
|
|
||||||
|
|
||||||
// Extract BSS count from controller's global capabilities register
|
|
||||||
#define HDA_BSS_COUNT(GCAP) ((GCAP >> 3) & 0x1F)
|
|
||||||
|
|
||||||
///
|
|
||||||
// Calculate offset of stream descriptors
|
|
||||||
#define CALCULATE_ISSN_OFFSET(StreamIndex) (HDA_OFFSET_SD0CTL + (StreamIndex * 0x20))
|
|
||||||
#define CALCULATE_OSSN_OFFSET(StreamIndex,GCAP) (HDA_OFFSET_SD0CTL + (HDA_ISS_COUNT(GCAP) * 0x20 ) + (StreamIndex * 0x20))
|
|
||||||
#define CALCULATE_BSSN_OFFSET(StreamIndex,GCAP) (HDA_OFFSET_SD0CTL + (HDA_ISS_COUNT(GCAP) * 0x20) + (HDA_OSS_COUNT(GCAP) * 0x20) + (StreamIndex * 0x20))
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t StreamReset: 1;
|
|
||||||
uint8_t StreamRun: 1;
|
|
||||||
uint8_t InterruptOnCompletionEnable: 1;
|
|
||||||
uint8_t FIFOErrorInterruptEnable: 1;
|
|
||||||
uint8_t DescriptorErrorInterruptEnable: 1;
|
|
||||||
uint8_t Reserved1: 3;
|
|
||||||
uint8_t Reserved2;
|
|
||||||
uint8_t StrippeControl: 2;
|
|
||||||
uint8_t TrafficPriority: 1;
|
|
||||||
uint8_t BidirectionalDirectionControl: 1;
|
|
||||||
uint8_t StreamNumber: 4;
|
|
||||||
} HDA_CONTROLLER_STREAM_DESCRIPTOR_CONTROL;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t SD0CTL[3]; // HDA_CONTROLLER_STREAM_DESCRIPTOR_CONTROL
|
|
||||||
uint8_t SD0STS;
|
|
||||||
uint32_t SD0LPIB;
|
|
||||||
uint32_t SD0CBL;
|
|
||||||
uint16_t SD0LVI;
|
|
||||||
uint16_t Rsvd8;
|
|
||||||
uint16_t SD0FIFOS;
|
|
||||||
uint16_t SD0FMT;
|
|
||||||
uint32_t Rsvd9;
|
|
||||||
uint32_t SD0BDPL;
|
|
||||||
uint32_t SD0BDPU;
|
|
||||||
} HDA_CONTROLLER_STREAM_DESCRIPTOR;
|
|
||||||
|
|
||||||
// HDA controller register set
|
|
||||||
// HDA Specification 1.0a page 27
|
|
||||||
typedef struct {
|
|
||||||
uint16_t GCAP;
|
|
||||||
uint8_t VMIN;
|
|
||||||
uint8_t VMAJ;
|
|
||||||
uint16_t OUTPAY;
|
|
||||||
uint16_t INPAY;
|
|
||||||
uint32_t GCTL;
|
|
||||||
uint16_t WAKEEN;
|
|
||||||
uint16_t STATESTS;
|
|
||||||
uint16_t GSTS;
|
|
||||||
uint8_t Rsvd0[6];
|
|
||||||
uint16_t OUTSTRMPAY;
|
|
||||||
uint16_t INSTRMPAY;
|
|
||||||
uint32_t Rsvd;
|
|
||||||
uint32_t INTCTL;
|
|
||||||
uint32_t INTSTS;
|
|
||||||
uint8_t Rsvd1[8];
|
|
||||||
uint32_t WALCLK;
|
|
||||||
uint32_t Rsvd2;
|
|
||||||
uint32_t SSYNC;
|
|
||||||
uint32_t Rsvd3;
|
|
||||||
uint32_t CORBLBASE;
|
|
||||||
uint32_t CORBUBASE;
|
|
||||||
uint16_t CORBWP;
|
|
||||||
uint16_t CORBRP;
|
|
||||||
uint8_t CORBCTL;
|
|
||||||
uint8_t CORBSTS;
|
|
||||||
uint8_t CORBSIZE;
|
|
||||||
uint8_t Rsvd4;
|
|
||||||
uint32_t RIRBLBASE;
|
|
||||||
uint32_t RIRBUBASE;
|
|
||||||
uint16_t RIRBWP;
|
|
||||||
uint16_t RINTCNT;
|
|
||||||
uint8_t RIRBCTL;
|
|
||||||
uint8_t RIRBSTS;
|
|
||||||
uint8_t RIRBSIZE;
|
|
||||||
uint8_t Rsvd5;
|
|
||||||
uint32_t ICOI;
|
|
||||||
uint32_t ICII;
|
|
||||||
uint16_t ICIS;
|
|
||||||
uint8_t Rsvd6[6];
|
|
||||||
uint32_t DPIBLBASE;
|
|
||||||
uint32_t DPIBUBASE;
|
|
||||||
uint8_t Rsvd7[8];
|
|
||||||
|
|
||||||
HDA_CONTROLLER_STREAM_DESCRIPTOR *ISS;
|
|
||||||
HDA_CONTROLLER_STREAM_DESCRIPTOR *OSS;
|
|
||||||
HDA_CONTROLLER_STREAM_DESCRIPTOR *BSS;
|
|
||||||
|
|
||||||
} HDA_CONTROLLER_REGISTER_SET;
|
|
||||||
|
|
||||||
// Executable verbs of widgets on a HDA compatible codec
|
|
||||||
// HDA Specification 1.0a page 218
|
|
||||||
typedef enum {
|
|
||||||
HDA_VRB_GET_PARAMETER = 0xF00,
|
|
||||||
HDA_VRB_GET_CONNECTION_SELECT = 0xF01,
|
|
||||||
HDA_VRB_GET_GET_CONNECTION_LIST_ENTRY = 0xF02,
|
|
||||||
HDA_VRB_GET_PROCESSING_STATE = 0xF03,
|
|
||||||
|
|
||||||
// These are widget dependent
|
|
||||||
HDA_VRB_GET_COEFFICIENT_INDEX = 0xD,
|
|
||||||
HDA_VRB_GET_PROCESSING_COEFFICIENT = 0xC,
|
|
||||||
HDA_VRB_GET_AMPLIFIER_GAIN_MUTE = 0xBA0,
|
|
||||||
HDA_VRB_GET_STREAM_FORMAT = 0xA,
|
|
||||||
|
|
||||||
HDA_VRB_GET_DIGITAL_CONVERTER_1 = 0xF0D,
|
|
||||||
//HDA_VRB_GET_DIGITAL_CONVERTER_2 = 0xF0D,
|
|
||||||
//HDA_VRB_GET_DIGITAL_CONVERTER_3 = 0xF0D,
|
|
||||||
//HDA_VRB_GET_DIGITAL_CONVERTER_4 = 0xF0D,
|
|
||||||
|
|
||||||
HDA_VRB_GET_POWER_STATE = 0xF05,
|
|
||||||
HDA_VRB_GET_CHANNEL_STREAM_ID = 0xF06,
|
|
||||||
HDA_VRB_GET_SDI_SELECT = 0xF04,
|
|
||||||
HDA_VRB_GET_PIN_WIDGET_CONTROL = 0xF07,
|
|
||||||
HDA_VRB_GET_UNSOLICITED_ENABLE = 0xF08,
|
|
||||||
HDA_VRB_GET_PIN_SENSE = 0xF09,
|
|
||||||
HDA_VRB_GET_EAPD_BTL_ENABLE = 0xF0C,
|
|
||||||
HDA_VRB_GET_ALL_GPI_CONTROLS_F10 = 0xF10,
|
|
||||||
HDA_VRB_GET_ALL_GPI_CONTROLS_F11 = 0xF11,
|
|
||||||
HDA_VRB_GET_ALL_GPI_CONTROLS_F12 = 0xF12,
|
|
||||||
HDA_VRB_GET_ALL_GPI_CONTROLS_F13 = 0xF13,
|
|
||||||
HDA_VRB_GET_ALL_GPI_CONTROLS_F14 = 0xF14,
|
|
||||||
HDA_VRB_GET_ALL_GPI_CONTROLS_F15 = 0xF15,
|
|
||||||
HDA_VRB_GET_ALL_GPI_CONTROLS_F16 = 0xF16,
|
|
||||||
HDA_VRB_GET_ALL_GPI_CONTROLS_F17 = 0xF17,
|
|
||||||
HDA_VRB_GET_ALL_GPI_CONTROLS_F18 = 0xF18,
|
|
||||||
HDA_VRB_GET_ALL_GPI_CONTROLS_F19 = 0xF19,
|
|
||||||
HDA_VRB_GET_ALL_GPI_CONTROLS_F1A = 0xF1A,
|
|
||||||
HDA_VRB_GET_BEEP_GENERATION_CONTROL = 0xF0A,
|
|
||||||
HDA_VRB_GET_VOLUME_KNOB_CONTROL = 0xF0F,
|
|
||||||
HDA_VRB_GET_IMPLEMENTATION_ID_BYTE_0 = 0xF20,
|
|
||||||
//HDA_VRB_GET_IMPLEMENTATION_ID_BYTE_1 = 0xF20,
|
|
||||||
//HDA_VRB_GET_IMPLEMENTATION_ID_BYTE_2 = 0xF20,
|
|
||||||
//HDA_VRB_GET_IMPLEMENTATION_ID_BYTE_3 = 0xF20,
|
|
||||||
HDA_VRB_GET_CONFIG_DEFAULT_BYTE_0 = 0xF1C,
|
|
||||||
//HDA_VRB_GET_CONFIG_DEFAULT_BYTE_1 = 0xF1C,
|
|
||||||
//HDA_VRB_GET_CONFIG_DEFAULT_BYTE_2 = 0xF1C,
|
|
||||||
//HDA_VRB_GET_CONFIG_DEFAULT_BYTE_3 = 0xF1C,
|
|
||||||
HDA_VRB_GET_STRIPE_CONTROL = 0xF24,
|
|
||||||
HDA_VRB_GET_CONVERTER_CHANNEL_COUNT = 0xF2D,
|
|
||||||
HDA_VRB_GET_DIP_SIZE = 0xF2E,
|
|
||||||
HDA_VRB_GET_ELD_DATA = 0xF2F,
|
|
||||||
HDA_VRB_GET_DIP_INDEX = 0xF30,
|
|
||||||
HDA_VRB_GET_DIP_DATA = 0xF31,
|
|
||||||
HDA_VRB_GET_DIP_XMITCTRL = 0xF32,
|
|
||||||
HDA_VRB_GET_CONTENT_PROTECTION_CONTROL = 0xF33,
|
|
||||||
HDA_VRB_GET_ASP_CHANNEL_MAPPING = 0xF34,
|
|
||||||
|
|
||||||
HDA_VRB_SET_CONNECTION_SELECT = 0x701,
|
|
||||||
|
|
||||||
// These are widget dependent
|
|
||||||
HDA_VRB_SET_COEFFICIENT_INDEX = 0x5,
|
|
||||||
HDA_VRB_SET_PROCESSING_COEFFICIENT = 0x4,
|
|
||||||
HDA_VRB_SET_AMPLIFIER_GAIN_MUTE = 0x3B0,
|
|
||||||
HDA_VRB_SET_STREAM_FORMAT = 0x2,
|
|
||||||
|
|
||||||
HDA_VRB_SET_DIGITAL_CONVERTER_1 = 0x70D,
|
|
||||||
HDA_VRB_SET_DIGITAL_CONVERTER_2 = 0x70E,
|
|
||||||
HDA_VRB_SET_DIGITAL_CONVERTER_3 = 0x73E,
|
|
||||||
HDA_VRB_SET_DIGITAL_CONVERTER_4 = 0x73F,
|
|
||||||
HDA_VRB_SET_POWER_STATE = 0x705,
|
|
||||||
HDA_VRB_SET_CHANNEL_STREAM_ID = 0x706,
|
|
||||||
HDA_VRB_SET_SDI_SELECT = 0x704,
|
|
||||||
HDA_VRB_SET_PIN_WIDGET_CONTROL = 0x707,
|
|
||||||
HDA_VRB_SET_UNSOLICITED_ENABLE = 0x708,
|
|
||||||
HDA_VRB_SET_PIN_SENSE = 0x709,
|
|
||||||
HDA_VRB_SET_EAPD_BTL_ENABLE = 0x70C,
|
|
||||||
HDA_VRB_SET_ALL_GPI_CONTROLS_710 = 0x710,
|
|
||||||
HDA_VRB_SET_ALL_GPI_CONTROLS_711 = 0x711,
|
|
||||||
HDA_VRB_SET_ALL_GPI_CONTROLS_712 = 0x712,
|
|
||||||
HDA_VRB_SET_ALL_GPI_CONTROLS_713 = 0x713,
|
|
||||||
HDA_VRB_SET_ALL_GPI_CONTROLS_714 = 0x714,
|
|
||||||
HDA_VRB_SET_ALL_GPI_CONTROLS_715 = 0x715,
|
|
||||||
HDA_VRB_SET_ALL_GPI_CONTROLS_716 = 0x716,
|
|
||||||
HDA_VRB_SET_ALL_GPI_CONTROLS_717 = 0x717,
|
|
||||||
HDA_VRB_SET_ALL_GPI_CONTROLS_718 = 0x718,
|
|
||||||
HDA_VRB_SET_ALL_GPI_CONTROLS_719 = 0x719,
|
|
||||||
HDA_VRB_SET_ALL_GPI_CONTROLS_71A = 0x71A,
|
|
||||||
HDA_VRB_SET_BEEP_GENERATION_CONTROL = 0x70A,
|
|
||||||
HDA_VRB_SET_VOLUME_KNOB_CONTROL = 0x70F,
|
|
||||||
HDA_VRB_SET_IMPLEMENTATION_ID_BYTE_0 = 0x720,
|
|
||||||
HDA_VRB_SET_IMPLEMENTATION_ID_BYTE_1 = 0x721,
|
|
||||||
HDA_VRB_SET_IMPLEMENTATION_ID_BYTE_2 = 0x722,
|
|
||||||
HDA_VRB_SET_IMPLEMENTATION_ID_BYTE_3 = 0x723,
|
|
||||||
HDA_VRB_SET_CONFIG_DEFAULT_BYTE_0 = 0x71C,
|
|
||||||
HDA_VRB_SET_CONFIG_DEFAULT_BYTE_1 = 0x71D,
|
|
||||||
HDA_VRB_SET_CONFIG_DEFAULT_BYTE_2 = 0x71E,
|
|
||||||
HDA_VRB_SET_CONFIG_DEFAULT_BYTE_3 = 0x723,
|
|
||||||
HDA_VRB_SET_STRIPE_CONTROL = 0x724,
|
|
||||||
HDA_VRB_SET_CONVERTER_CHANNEL_COUNT = 0x72D,
|
|
||||||
HDA_VRB_SET_DIP_INDEX = 0x730,
|
|
||||||
HDA_VRB_SET_DIP_DATA = 0x731,
|
|
||||||
HDA_VRB_SET_DIP_XMITCTRL = 0x732,
|
|
||||||
HDA_VRB_SET_CONTENT_PROTECTION_CONTROL = 0x733,
|
|
||||||
HDA_VRB_SET_ASP_CHANNEL_MAPPING = 0x734,
|
|
||||||
|
|
||||||
HDA_VRB_SET_RESET = 0x7FF
|
|
||||||
} HDA_VERB;
|
|
||||||
|
|
||||||
#define HDA_START_PROCESSING_IMMEDIATE_COMMAND 0x01
|
|
||||||
|
|
||||||
// Extract the total node count from a SubordinateNodeCount property
|
|
||||||
#define HDA_SUB_NODE_COUNT_TOTAL_NODE(Subordinate) (Subordinate & 0xFF)
|
|
||||||
|
|
||||||
// Extract the total node count from a SubordinateNodeCount poperty
|
|
||||||
#define HDA_SUB_NODE_COUNT_START_NODE(Subordinate) ((Subordinate >> 16) & 0xFF)
|
|
||||||
|
|
||||||
// Extract the node type from a FunctionGroup property
|
|
||||||
#define HDA_NODE_TYPE(FunctionGroupType) (FunctionGroupType & 0xFF)
|
|
||||||
|
|
||||||
// Check if a given function group can generate unsolicited responses
|
|
||||||
#define HDA_UNSOLICITED_RESPONSE_CAPABLE(FunctionGroupType) ((FunctionGroupType >> 8) & 0x01)
|
|
||||||
|
|
||||||
// Extract widget type from widget capabilities information
|
|
||||||
#define HDA_WIDGET_TYPE(WidgetCap) ((WidgetCap >> 20) & 0xF)
|
|
||||||
|
|
||||||
// HDA command with an 8-bit payload
|
|
||||||
typedef struct {
|
|
||||||
uint32_t VerbPayload : 8;
|
|
||||||
uint32_t VerbIdent : 12; // verb
|
|
||||||
uint32_t NID : 8; // node ID
|
|
||||||
uint32_t CAd : 4; // codec address
|
|
||||||
uint8_t Reserved;
|
|
||||||
} HDA_COMMAND_FIELD_8BIT_PAYLOAD;
|
|
||||||
|
|
||||||
// HDA command with an 16-bit payload
|
|
||||||
typedef struct {
|
|
||||||
uint32_t VerbPayload : 16;
|
|
||||||
uint32_t VerbIdent : 4; // verb
|
|
||||||
uint32_t NID : 8; // node ID
|
|
||||||
uint32_t CAd : 4; // codec address
|
|
||||||
uint8_t Reserved;
|
|
||||||
} HDA_COMMAND_FIELD_16BIT_PAYLOAD;
|
|
||||||
|
|
||||||
// Stream format
|
|
||||||
// HDA Specification 1.0a page 58
|
|
||||||
typedef struct {
|
|
||||||
uint16_t NumberOfChannels : 4;
|
|
||||||
uint16_t BitsPerSample : 3;
|
|
||||||
uint16_t Reserved : 1;
|
|
||||||
uint16_t SampleBaseRateBaseDivisor : 3;
|
|
||||||
uint16_t SampleBaseRateMultiple : 3;
|
|
||||||
uint16_t SampleBaseRate : 1;
|
|
||||||
uint16_t StreamType : 1;
|
|
||||||
} HDA_STREAM_FORMAT;
|
|
||||||
|
|
||||||
// Stream descriptor format
|
|
||||||
// HDA Specification 1.0a page 48
|
|
||||||
typedef struct {
|
|
||||||
uint16_t NumberOfChannels : 4;
|
|
||||||
uint16_t BitsPerSample : 3;
|
|
||||||
uint16_t Reserved : 1;
|
|
||||||
uint16_t SampleBaseRateBaseDivisor : 3;
|
|
||||||
uint16_t SampleBaseRateMultiple : 3;
|
|
||||||
uint16_t SampleBaseRate : 1;
|
|
||||||
uint16_t Reserved2 : 1;
|
|
||||||
} HDA_STREAM_DESCRIPTOR_FORMAT;
|
|
||||||
|
|
||||||
#define PCM_STRUCT_BITS_PER_SAMPLE_8 0
|
|
||||||
#define PCM_STRUCT_BITS_PER_SAMPLE_16 1
|
|
||||||
#define PCM_STRUCT_BITS_PER_SAMPLE_20 2
|
|
||||||
#define PCM_STRUCT_BITS_PER_SAMPLE_24 3
|
|
||||||
#define PCM_STRUCT_BITS_PER_SAMPLE_32 4
|
|
||||||
|
|
||||||
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_1 0
|
|
||||||
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_2 1
|
|
||||||
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_3 2
|
|
||||||
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_4 3
|
|
||||||
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_5 4
|
|
||||||
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_6 5
|
|
||||||
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_7 6
|
|
||||||
|
|
||||||
//192 kHz, 176.4 kHz
|
|
||||||
#define PCM_STRUCT_SAMPLE_BASE_MULTIPLE_X4 3
|
|
||||||
//144 kHz
|
|
||||||
#define PCM_STRUCT_SAMPLE_BASE_MULTIPLE_X3 2
|
|
||||||
//96 kHz, 88.2 kHz, 32 kHz
|
|
||||||
#define PCM_STRUCT_SAMPLE_BASE_MULTIPLE_X2 1
|
|
||||||
//48KHz/44.1kHz or less
|
|
||||||
#define PCM_STRUCT_SAMPLE_BASE_MULTIPLE_48_OR_LESS 0
|
|
||||||
|
|
||||||
#define PCM_STRUCT_SAMPLE_BASE_44_1KHZ 1
|
|
||||||
#define PCM_STRUCT_SAMPLE_BASE_48KHZ 0
|
|
||||||
|
|
||||||
#define PCM_STRUCT_TYPE_PCM 0
|
|
||||||
#define PCM_STRUCT_TYPE_NON_PCM 1
|
|
||||||
|
|
||||||
// All possible parameters for executing HDA_VRB_GET_PARAMETER
|
|
||||||
// HDA Specification 1.0a page 217
|
|
||||||
typedef enum {
|
|
||||||
HDA_PARAM_VENDOR_ID = 0x00,
|
|
||||||
HDA_PARAM_REVISION_ID = 0x02,
|
|
||||||
HDA_PARAM_SUBORDINATE_NODE_COUNT = 0x04,
|
|
||||||
HDA_PARAM_FUNCTION_GROUP_TYPE = 0x05,
|
|
||||||
HDA_PARAM_AUDIO_FUNC_CAP = 0x08,
|
|
||||||
HDA_PARAM_AUDIO_WIDGET_CAP = 0x09,
|
|
||||||
HDA_PARAM_SAMPLE_SIZE_RATE_CAP = 0x0A,
|
|
||||||
HDA_PARAM_STREAM_FORMATS = 0x0B,
|
|
||||||
HDA_PARAM_PIN_CAP = 0x0C,
|
|
||||||
HDA_PARAM_INPUT_AMP_CAP = 0x0D,
|
|
||||||
HDA_PARAM_OUTPUT_AMP_CAP = 0x12,
|
|
||||||
HDA_PARAM_CONNECTION_LIST_LENGTH = 0x0E,
|
|
||||||
HDA_PARAM_SUPPORTED_POWER_STATES = 0x0F,
|
|
||||||
HDA_PARAM_PROCESSING_CAP = 0x10,
|
|
||||||
HDA_PARAM_GPIO_COUNT = 0x11,
|
|
||||||
HDA_PARAM_VOLUME_KNOB_CAP = 0x13
|
|
||||||
} HDA_PARAMETER;
|
|
||||||
|
|
||||||
// All possible parameters widget types present
|
|
||||||
typedef enum {
|
|
||||||
HDA_WIDGET_TYPE_AUDIO_OUTPUT = 0x0,
|
|
||||||
HDA_WIDGET_TYPE_AUDIO_INPUT = 0x1,
|
|
||||||
HDA_WIDGET_TYPE_AUDIO_MIXER = 0x2,
|
|
||||||
HDA_WIDGET_TYPE_AUDIO_SELECTOR = 0x3,
|
|
||||||
HDA_WIDGET_TYPE_AUDIO_PIN_CONPLEX = 0x4,
|
|
||||||
HDA_WIDGET_TYPE_AUDIO_POWER = 0x5,
|
|
||||||
HDA_WIDGET_TYPE_AUDIO_VOLUME_KNOB = 0x6,
|
|
||||||
HDA_WIDGET_TYPE_AUDIO_BEEP_GENERATOR = 0x7,
|
|
||||||
HDA_WIDGET_TYPE_AUDIO_VENDOR_DEFINED = 0xF
|
|
||||||
} HDA_WIDGET_TYPE;
|
|
||||||
|
|
||||||
// Function group types
|
|
||||||
typedef enum {
|
|
||||||
HDA_FUNCTION_GROUP_TYPE_AUDIO = 0x1,
|
|
||||||
HDA_FUNCTION_GROUP_TYPE_MODEM = 0x2
|
|
||||||
} HDA_FUNCTION_GROUP_TYPE;
|
|
||||||
|
|
||||||
// All possible node types available at a codec
|
|
||||||
typedef enum {
|
|
||||||
HDA_NODE_ROOT = 0x0,
|
|
||||||
HDA_NODE_FUNCTION_GROUP = 0x1,
|
|
||||||
HDA_NODE_WIDGET = 0x2,
|
|
||||||
HDA_UNKNOWN = 0xFF
|
|
||||||
} HDA_NODE_TYPE;
|
|
||||||
|
|
||||||
// Empty payload
|
|
||||||
#define HDA_VRB_EMPTY_PAYLOAD 0
|
|
||||||
|
|
||||||
// All possible power stats a node can present
|
|
||||||
// HDA Specification 1.0a page 151
|
|
||||||
typedef enum {
|
|
||||||
HDA_POWER_D0 = 0x0,
|
|
||||||
HDA_POWER_D1 = 0x1,
|
|
||||||
HDA_POWER_D2 = 0x2,
|
|
||||||
HDA_POWER_D3 = 0x3,
|
|
||||||
HDA_POWER_D3_COLD = 0x4,
|
|
||||||
} HDA_POWER_STATE;
|
|
||||||
|
|
||||||
// HDA codec node
|
|
||||||
struct Node {
|
|
||||||
uint32_t NodeId;
|
|
||||||
HDA_NODE_TYPE NodeType;
|
|
||||||
HDA_WIDGET_TYPE WidgetType;
|
|
||||||
uint32_t VendorId;
|
|
||||||
uint32_t RevisionId;
|
|
||||||
uint32_t StartingChildNodeAddess;
|
|
||||||
uint32_t SubordinateNodeCount;
|
|
||||||
uint32_t FunctionGroupType;
|
|
||||||
uint32_t FuncCap;
|
|
||||||
uint32_t WidgetCap;
|
|
||||||
uint32_t SampleSizeRateCap;
|
|
||||||
uint32_t StreamFormat;
|
|
||||||
uint32_t PinCap;
|
|
||||||
uint32_t InputAmpCap;
|
|
||||||
uint32_t OutputAmpCap;
|
|
||||||
uint32_t ConnectionListLength;
|
|
||||||
uint32_t SupportedPowerStates;
|
|
||||||
uint32_t ProcessingCap;
|
|
||||||
uint32_t GPIOCount;
|
|
||||||
uint32_t VolKnobCap;
|
|
||||||
|
|
||||||
uint32_t PowerState;
|
|
||||||
|
|
||||||
uint32_t RightGain;
|
|
||||||
uint32_t LeftGain;
|
|
||||||
|
|
||||||
uint32_t ChannelStreamId;
|
|
||||||
|
|
||||||
struct Node *ChildNodes;
|
|
||||||
};
|
|
||||||
|
|
||||||
// HDA Specification 1.0a page 142
|
|
||||||
typedef struct {
|
|
||||||
uint32_t Response;
|
|
||||||
uint8_t Reserved : 2;
|
|
||||||
uint8_t UnSol : 1;
|
|
||||||
uint8_t Valid : 1;
|
|
||||||
uint8_t Unused : 4;
|
|
||||||
} HDA_RESPONSE_FIELD;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint64_t Address;
|
|
||||||
uint32_t Length;
|
|
||||||
uint32_t IntrptOnComp : 1;
|
|
||||||
uint32_t Resv : 31;
|
|
||||||
} HDA_BUFFER_DESCRIPTOR_LIST_ENTRY;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
HDA_BUFFER_DESCRIPTOR_LIST_ENTRY BDLEntry[HDA_BUFFER_DESC_LIST_MAX_ENTRIES];
|
|
||||||
} HDA_BUFFER_DESCRIPTOR_LIST;
|
|
||||||
|
|
||||||
EFI_STATUS InitHda();
|
|
||||||
|
|
||||||
EFI_STATUS AllocateCORBBuffer(PCI_HDA_REGION* PcieDeviceConfigSpace);
|
|
||||||
EFI_STATUS AllocateRIRBBuffer(PCI_HDA_REGION* PcieDeviceConfigSpace);
|
|
||||||
|
|
||||||
EFI_STATUS FillCodecNode(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint32_t CurrentNodeId,
|
|
||||||
HDA_NODE_TYPE NodeType,
|
|
||||||
struct Node *CurrentNode);
|
|
||||||
|
|
||||||
EFI_STATUS GetNodeById(struct Node *RootNode,
|
|
||||||
uint32_t NodeIdToSearch,
|
|
||||||
struct Node *NodeDetected);
|
|
||||||
|
|
||||||
EFI_STATUS GetCodecTree(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
struct Node *RootNode);
|
|
||||||
|
|
||||||
EFI_STATUS ReleaseCodecTree(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
struct Node *RootNode);
|
|
||||||
|
|
||||||
EFI_STATUS GetCodecData8BitPayload(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint8_t CodecAddress, uint8_t NodeId,
|
|
||||||
HDA_VERB Verb, uint8_t VerbPayload,
|
|
||||||
uint32_t *Response);
|
|
||||||
|
|
||||||
EFI_STATUS GetCodecData8BitPayloadCorbRirb(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint8_t CodecAddress, uint8_t NodeId,
|
|
||||||
HDA_VERB Verb, uint8_t VerbPayload,
|
|
||||||
uint32_t *Response);
|
|
||||||
|
|
||||||
EFI_STATUS GetCodecData16BitPayloadCorbRirb(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint8_t CodecAddress, uint8_t NodeId,
|
|
||||||
HDA_VERB Verb, uint16_t VerbPayload,
|
|
||||||
uint32_t *Response);
|
|
||||||
|
|
||||||
|
|
||||||
EFI_STATUS SendCommandToAllWidgets8BitPayload (
|
|
||||||
PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
HDA_VERB Verb, uint8_t VerbPayload);
|
|
||||||
|
|
||||||
EFI_STATUS SendCommandToAllWidgets16BitPayload (
|
|
||||||
PCI_HDA_REGION* PcieDeviceConfigSpace,
|
|
||||||
HDA_VERB Verb, uint16_t VerbPayload);
|
|
||||||
|
|
||||||
EFI_STATUS GetCodecData16BitPayload(PCI_HDA_REGION* PcieDeviceConfigSpace,
|
|
||||||
uint8_t CodecAddress, uint8_t NodeId,
|
|
||||||
HDA_VERB Verb, uint16_t VerbPayload,
|
|
||||||
uint32_t *Response);
|
|
||||||
|
|
||||||
uint32_t GetAmplifierGain(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint8_t NodeId, bool InputOutput,
|
|
||||||
bool LeftRight);
|
|
||||||
|
|
||||||
EFI_STATUS DisablePcieInterrupts(PCI_HDA_REGION *PcieDeviceConfigSpace);
|
|
||||||
|
|
||||||
EFI_STATUS EnablePcieNoSnoop(PCI_HDA_REGION *PcieDeviceConfigSpace);
|
|
||||||
|
|
||||||
EFI_STATUS AddDescriptorListEntryOss0(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
HDA_CONTROLLER_REGISTER_SET *ControllerRegisterSet,
|
|
||||||
uint64_t DataAddress,
|
|
||||||
uint32_t DataLength,
|
|
||||||
uint8_t BdlEntryIndex,
|
|
||||||
uint32_t SdxLastValidIndex);
|
|
||||||
|
|
||||||
EFI_STATUS AllocateStreamsPages(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
HDA_CONTROLLER_REGISTER_SET *ControllerRegisterSet);
|
|
||||||
|
|
||||||
#endif /* _HDA_HDA_H */
|
|
|
@ -1,289 +0,0 @@
|
||||||
/*********************************************************************************/
|
|
||||||
/* Module Name: pciconf.h */
|
|
||||||
/* Project: AurixOS */
|
|
||||||
/* */
|
|
||||||
/* Copyright (c) 2018-2025, Rafael Rodrigues Machado, Jozef Nagy */
|
|
||||||
/* All rights reserved. */
|
|
||||||
/* This program and the accompanying materials are licensed and made available */
|
|
||||||
/* under the terms and conditions of the BSD License which accompanies */
|
|
||||||
/* this distribution. The full text of the license may be found at */
|
|
||||||
/* http://opensource.org/licenses/bsd-license. */
|
|
||||||
/* */
|
|
||||||
/* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, */
|
|
||||||
/* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. */
|
|
||||||
/*********************************************************************************/
|
|
||||||
|
|
||||||
#include <lib/string.h>
|
|
||||||
#include <mm/mman.h>
|
|
||||||
#include <efi.h>
|
|
||||||
#include <efilib.h>
|
|
||||||
#include <print.h>
|
|
||||||
|
|
||||||
#include <hda.h>
|
|
||||||
#include <pciconf.h>
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
EFI_PCI_IO_PROTOCOL *HdaPciIoProtocol = NULL;
|
|
||||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgePciIoProtocol = NULL;
|
|
||||||
|
|
||||||
EFI_STATUS TearDownCommonBuffer(uint8_t *HostAddress,
|
|
||||||
uint64_t Length,
|
|
||||||
void *Mapping)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
Status = HdaPciIoProtocol->Unmap(HdaPciIoProtocol, Mapping);
|
|
||||||
if (EFI_ERROR(Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = HdaPciIoProtocol->FreeBuffer(HdaPciIoProtocol, EFI_SIZE_TO_PAGES(Length), (void *)HostAddress);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS ReleaseHdaPciIoHandler()
|
|
||||||
{
|
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
/*
|
|
||||||
Status = TearDownCommonBuffer((uint8_t *)CorbAddress, 1024, CorbMapping);
|
|
||||||
if (!EFI_ERROR(Status)) {
|
|
||||||
Status = TearDownCommonBuffer((uint8_t *)RirbAddress, 2048, RirbMapping);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS SetupCommonBuffer(uint8_t **HostAddress,
|
|
||||||
uint64_t Length,
|
|
||||||
void **Mapping,
|
|
||||||
uint64_t Alignment)
|
|
||||||
{
|
|
||||||
(void)Mapping;
|
|
||||||
(void)Alignment;
|
|
||||||
|
|
||||||
*HostAddress = mem_alloc(Length);
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS GetHdaPciIoHandler()
|
|
||||||
{
|
|
||||||
EFI_HANDLE *DetectedHandles = NULL;
|
|
||||||
EFI_UINTN DetectedHandlesCount = 0;
|
|
||||||
EFI_UINTN CurrentHandle = 0;
|
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
|
||||||
EFI_GUID PciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
|
|
||||||
|
|
||||||
EFI_UINTN SegmentNumber;
|
|
||||||
EFI_UINTN BusNumber;
|
|
||||||
EFI_UINTN DeviceNumber;
|
|
||||||
EFI_UINTN FunctionNumber;
|
|
||||||
|
|
||||||
if (HdaPciIoProtocol == NULL) {
|
|
||||||
Status = gBootServices->LocateHandleBuffer(ByProtocol,
|
|
||||||
&PciIoProtocolGuid,
|
|
||||||
NULL,
|
|
||||||
&DetectedHandlesCount,
|
|
||||||
&DetectedHandles);
|
|
||||||
|
|
||||||
if (!EFI_ERROR(Status)) {
|
|
||||||
for (CurrentHandle = 0; CurrentHandle < DetectedHandlesCount; CurrentHandle++) {
|
|
||||||
Status = gBootServices->OpenProtocol(DetectedHandles[CurrentHandle],
|
|
||||||
&PciIoProtocolGuid,
|
|
||||||
(VOID**) &HdaPciIoProtocol,
|
|
||||||
gImageHandle,
|
|
||||||
NULL,
|
|
||||||
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
|
||||||
|
|
||||||
Status = HdaPciIoProtocol->GetLocation(HdaPciIoProtocol,
|
|
||||||
&SegmentNumber,
|
|
||||||
&BusNumber,
|
|
||||||
&DeviceNumber,
|
|
||||||
&FunctionNumber);
|
|
||||||
|
|
||||||
debug("GetHdaPciIoHandler(): Found device %llu:%llu:%llu\n", SegmentNumber, BusNumber, DeviceNumber, FunctionNumber);
|
|
||||||
|
|
||||||
// This means a HDA controller was detected
|
|
||||||
if (BusNumber == HDA_BUS && DeviceNumber == HDA_DEV && FunctionNumber == HDA_FUNC) {
|
|
||||||
debug("Handle detected\r\n");
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
gBootServices->CloseProtocol(DetectedHandles[CurrentHandle],
|
|
||||||
&PciIoProtocolGuid,
|
|
||||||
gImageHandle,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS GetRootBridgeIoHandler()
|
|
||||||
{
|
|
||||||
EFI_UINTN handleCount = 0;
|
|
||||||
EFI_HANDLE *DetectedHandles = NULL;
|
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
|
||||||
EFI_GUID PciRootBridgeIoProtocolGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
|
|
||||||
|
|
||||||
if (RootBridgePciIoProtocol == NULL) {
|
|
||||||
Status = gBootServices->LocateHandleBuffer(ByProtocol,
|
|
||||||
&PciRootBridgeIoProtocolGuid,
|
|
||||||
NULL,
|
|
||||||
&handleCount,
|
|
||||||
&DetectedHandles);
|
|
||||||
|
|
||||||
if (!EFI_ERROR(Status)) {
|
|
||||||
Status = gBootServices->OpenProtocol(DetectedHandles[0],
|
|
||||||
&PciRootBridgeIoProtocolGuid,
|
|
||||||
(void **)&RootBridgePciIoProtocol,
|
|
||||||
gImageHandle,
|
|
||||||
NULL,
|
|
||||||
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS GetControllerRegisterSet(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
HDA_CONTROLLER_REGISTER_SET *ControllerRegisterSet)
|
|
||||||
{
|
|
||||||
uint64_t IssCount = 0;
|
|
||||||
uint64_t OssCount = 0;
|
|
||||||
uint64_t BssCount = 0;
|
|
||||||
|
|
||||||
uint64_t HdaControllerBar = (PcieDeviceConfigSpace->HDBARL & 0xFFFFFFF0);
|
|
||||||
|
|
||||||
RootBridgePciIoProtocol->Mem.Read(RootBridgePciIoProtocol, EfiPciWidthUint8, HdaControllerBar, sizeof(HDA_CONTROLLER_REGISTER_SET) / sizeof(uint8_t), (void *)ControllerRegisterSet);
|
|
||||||
IssCount = HDA_ISS_COUNT(ControllerRegisterSet->GCAP);
|
|
||||||
OssCount = HDA_OSS_COUNT(ControllerRegisterSet->GCAP);
|
|
||||||
BssCount = HDA_BSS_COUNT(ControllerRegisterSet->GCAP);
|
|
||||||
|
|
||||||
if (IssCount > 0) {
|
|
||||||
ControllerRegisterSet->ISS = mem_alloc(IssCount * sizeof(HDA_CONTROLLER_STREAM_DESCRIPTOR));
|
|
||||||
memset(ControllerRegisterSet->ISS, 0, IssCount * sizeof(HDA_CONTROLLER_STREAM_DESCRIPTOR));
|
|
||||||
RootBridgePciIoProtocol->Mem.Read(RootBridgePciIoProtocol, EfiPciWidthUint8, HdaControllerBar + CALCULATE_ISSN_OFFSET(0), (sizeof(HDA_CONTROLLER_STREAM_DESCRIPTOR) * IssCount) / sizeof(uint8_t), (void *)ControllerRegisterSet->ISS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OssCount > 0) {
|
|
||||||
ControllerRegisterSet->OSS = mem_alloc(OssCount * sizeof(HDA_CONTROLLER_STREAM_DESCRIPTOR));
|
|
||||||
memset(ControllerRegisterSet->OSS, 0, OssCount * sizeof(HDA_CONTROLLER_STREAM_DESCRIPTOR));
|
|
||||||
RootBridgePciIoProtocol->Mem.Read(RootBridgePciIoProtocol, EfiPciWidthUint8, HdaControllerBar + CALCULATE_OSSN_OFFSET(0, ControllerRegisterSet->GCAP), (sizeof(HDA_CONTROLLER_STREAM_DESCRIPTOR) * OssCount) / sizeof(uint8_t), (void *)ControllerRegisterSet->OSS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BssCount > 0) {
|
|
||||||
ControllerRegisterSet->BSS = mem_alloc(BssCount * sizeof(HDA_CONTROLLER_STREAM_DESCRIPTOR));
|
|
||||||
RootBridgePciIoProtocol->Mem.Read(RootBridgePciIoProtocol, EfiPciWidthUint8, HdaControllerBar + CALCULATE_BSSN_OFFSET(0, ControllerRegisterSet->GCAP), (sizeof(HDA_CONTROLLER_STREAM_DESCRIPTOR) * BssCount) / sizeof(uint8_t), (void *)ControllerRegisterSet->BSS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS WritePciMemory(uint64_t Address,
|
|
||||||
void *Value,
|
|
||||||
uint64_t Count,
|
|
||||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width)
|
|
||||||
{
|
|
||||||
return RootBridgePciIoProtocol->Mem.Write(RootBridgePciIoProtocol, Width, Address, Count, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS ReadPciMemory(uint64_t Address,
|
|
||||||
void *Value,
|
|
||||||
uint64_t Count,
|
|
||||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width)
|
|
||||||
{
|
|
||||||
return RootBridgePciIoProtocol->Mem.Read(RootBridgePciIoProtocol, Width, Address, Count, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS WriteControllerRegister(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint64_t Offset,
|
|
||||||
void *Value,
|
|
||||||
uint64_t Count,
|
|
||||||
uint8_t BarIndex,
|
|
||||||
EFI_PCI_IO_PROTOCOL_WIDTH Width)
|
|
||||||
{
|
|
||||||
(void)PcieDeviceConfigSpace;
|
|
||||||
|
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
|
||||||
EFI_UINTN VariableWidth = 0;
|
|
||||||
|
|
||||||
switch (Width) {
|
|
||||||
case EfiPciWidthUint32:
|
|
||||||
VariableWidth = sizeof(uint32_t);
|
|
||||||
break;
|
|
||||||
case EfiPciWidthUint16:
|
|
||||||
VariableWidth = sizeof(uint16_t);
|
|
||||||
break;
|
|
||||||
case EfiPciWidthUint8:
|
|
||||||
VariableWidth = sizeof(uint8_t);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *ReadValue = mem_alloc(VariableWidth);
|
|
||||||
memset(ReadValue, 0, VariableWidth);
|
|
||||||
|
|
||||||
HdaPciIoProtocol->Mem.Write(HdaPciIoProtocol, Width, BarIndex, Offset, Count, Value);
|
|
||||||
Status = HdaPciIoProtocol->Mem.Read(HdaPciIoProtocol, Width, BarIndex, Offset, Count, ReadValue);
|
|
||||||
|
|
||||||
mem_free(ReadValue);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS ReadControllerRegister(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
EFI_UINT64 Offset,
|
|
||||||
void *Value,
|
|
||||||
EFI_UINTN Count,
|
|
||||||
EFI_PCI_IO_PROTOCOL_WIDTH Width)
|
|
||||||
{
|
|
||||||
EFI_UINT64 HdaControllerBar = (PcieDeviceConfigSpace->HDBARL & 0xFFFFFFF0);
|
|
||||||
return RootBridgePciIoProtocol->Mem.Read(RootBridgePciIoProtocol, (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width, HdaControllerBar + Offset, Count, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS ReadControllerPcieConfiguration(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint64_t Offset,
|
|
||||||
void *Value,
|
|
||||||
uint64_t Count,
|
|
||||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width)
|
|
||||||
{
|
|
||||||
EFI_UINT64 Address = (HDA_BUS << 24) | (HDA_DEV << 16) | (HDA_FUNC << 8) | Offset;
|
|
||||||
return RootBridgePciIoProtocol->Pci.Read(RootBridgePciIoProtocol, Width, Address, Count, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS WriteControllerPcieConfiguration(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint64_t Offset,
|
|
||||||
void *Value,
|
|
||||||
uint64_t Count,
|
|
||||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width)
|
|
||||||
{
|
|
||||||
EFI_UINT64 Address = (HDA_BUS << 24) | (HDA_DEV << 16) | (HDA_FUNC << 8) | Offset;
|
|
||||||
return RootBridgePciIoProtocol->Pci.Write(RootBridgePciIoProtocol, Width, Address, Count, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS GetPcieConfigSpace(EFI_UINTN Bus,
|
|
||||||
EFI_UINTN Device,
|
|
||||||
EFI_UINTN Function,
|
|
||||||
PCI_HDA_REGION *PcieDeviceConfigSpace)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
if (PcieDeviceConfigSpace == NULL) {
|
|
||||||
debug("PcieDeviceConfigSpace==NULL\n");
|
|
||||||
}
|
|
||||||
debug("Width=%u\n", (sizeof(PCI_HDA_REGION) / sizeof(uint8_t)));
|
|
||||||
Status = RootBridgePciIoProtocol->Pci.Read(RootBridgePciIoProtocol, EfiPciIoWidthUint8,
|
|
||||||
EFI_PCI_ADDRESS(Bus, Device, Function, 0),
|
|
||||||
sizeof(PCI_HDA_REGION) / sizeof(EFI_UINT8),
|
|
||||||
(void *)PcieDeviceConfigSpace);
|
|
||||||
if (EFI_ERROR(Status)) {
|
|
||||||
debug("GetPcieConfigSpace(): %s (%x)\n", efi_status_to_str(Status), Status);
|
|
||||||
}
|
|
||||||
return Status;
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*********************************************************************************/
|
|
||||||
/* Module Name: pciconf.h */
|
|
||||||
/* Project: AurixOS */
|
|
||||||
/* */
|
|
||||||
/* Copyright (c) 2018-2025, Rafael Rodrigues Machado, Jozef Nagy */
|
|
||||||
/* All rights reserved. */
|
|
||||||
/* This program and the accompanying materials are licensed and made available */
|
|
||||||
/* under the terms and conditions of the BSD License which accompanies */
|
|
||||||
/* this distribution. The full text of the license may be found at */
|
|
||||||
/* http://opensource.org/licenses/bsd-license. */
|
|
||||||
/* */
|
|
||||||
/* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, */
|
|
||||||
/* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. */
|
|
||||||
/*********************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _HDA_PCICONF_H
|
|
||||||
#define _HDA_PCICONF_H
|
|
||||||
|
|
||||||
#include <hda.h>
|
|
||||||
#include <efi.h>
|
|
||||||
#include <efilib.h>
|
|
||||||
|
|
||||||
EFI_STATUS TearDownCommonBuffer(uint8_t *HostAddress,
|
|
||||||
uint64_t Length,
|
|
||||||
void *Mapping);
|
|
||||||
|
|
||||||
EFI_STATUS ReleaseHdaPciIoHandler();
|
|
||||||
|
|
||||||
EFI_STATUS SetupCommonBuffer(uint8_t **HostAddress,
|
|
||||||
uint64_t Length,
|
|
||||||
void **Mapping,
|
|
||||||
uint64_t Alignment);
|
|
||||||
|
|
||||||
EFI_STATUS GetHdaPciIoHandler();
|
|
||||||
EFI_STATUS GetRootBridgeIoHandler();
|
|
||||||
EFI_STATUS GetControllerRegisterSet(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
HDA_CONTROLLER_REGISTER_SET *ControllerRegisterSet);
|
|
||||||
|
|
||||||
EFI_STATUS WritePciMemory(uint64_t Address,
|
|
||||||
void *Value,
|
|
||||||
uint64_t Count,
|
|
||||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width);
|
|
||||||
|
|
||||||
EFI_STATUS ReadPciMemory(uint64_t Address,
|
|
||||||
void *Value,
|
|
||||||
uint64_t Count,
|
|
||||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width);
|
|
||||||
|
|
||||||
EFI_STATUS WriteControllerRegister(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint64_t Offset,
|
|
||||||
void *Value,
|
|
||||||
uint64_t Count,
|
|
||||||
uint8_t BarIndex,
|
|
||||||
EFI_PCI_IO_PROTOCOL_WIDTH Width);
|
|
||||||
|
|
||||||
EFI_STATUS ReadControllerRegister(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
EFI_UINT64 Offset,
|
|
||||||
void *Value,
|
|
||||||
EFI_UINTN Count,
|
|
||||||
EFI_PCI_IO_PROTOCOL_WIDTH Width);
|
|
||||||
|
|
||||||
EFI_STATUS ReadControllerPcieConfiguration(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint64_t Offset,
|
|
||||||
void *Value,
|
|
||||||
uint64_t Count,
|
|
||||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width);
|
|
||||||
|
|
||||||
EFI_STATUS WriteControllerPcieConfiguration(PCI_HDA_REGION *PcieDeviceConfigSpace,
|
|
||||||
uint64_t Offset,
|
|
||||||
void *Value,
|
|
||||||
uint64_t Count,
|
|
||||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width);
|
|
||||||
|
|
||||||
EFI_STATUS GetPcieConfigSpace(EFI_UINTN Bus,
|
|
||||||
EFI_UINTN Device,
|
|
||||||
EFI_UINTN Function,
|
|
||||||
PCI_HDA_REGION *PcieDeviceConfigSpace);
|
|
||||||
|
|
||||||
#endif /* _HDA_PCICONF_H */
|
|
|
@ -1 +0,0 @@
|
||||||
This place is for UEFI drivers only.
|
|
|
@ -25,103 +25,27 @@
|
||||||
#include <lib/string.h>
|
#include <lib/string.h>
|
||||||
#include <print.h>
|
#include <print.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include <sounds/chime.h>
|
#define INI_IMPLEMENTATION
|
||||||
#include <hda.h>
|
#include <config/ini.h>
|
||||||
#include <pciconf.h>
|
|
||||||
|
|
||||||
EFI_HANDLE gImageHandle;
|
EFI_HANDLE gImageHandle;
|
||||||
EFI_SYSTEM_TABLE *gSystemTable;
|
EFI_SYSTEM_TABLE *gSystemTable;
|
||||||
EFI_BOOT_SERVICES *gBootServices;
|
EFI_BOOT_SERVICES *gBootServices;
|
||||||
|
|
||||||
#define INITIAL_VOLUME 12
|
EFI_SIMPLE_POINTER_PROTOCOL *gPointerProtocol;
|
||||||
|
uint16_t mouse_resx;
|
||||||
uint8_t *AlignedDataBufferBdlEntry = NULL;
|
uint16_t mouse_resy;
|
||||||
uint8_t *SoundData = NULL;
|
|
||||||
uint64_t SoundDataSize = 0;
|
|
||||||
|
|
||||||
EFI_STATUS InitHdaControllerCodecAndBuffers(PCI_HDA_REGION *PcieDeviceConfigSpace, HDA_CONTROLLER_REGISTER_SET *ControllerRegisterSet)
|
|
||||||
{
|
|
||||||
uint32_t WriteValue = 0;
|
|
||||||
uint32_t Response = 0;
|
|
||||||
|
|
||||||
DisablePcieInterrupts(PcieDeviceConfigSpace);
|
|
||||||
EnablePcieNoSnoop(PcieDeviceConfigSpace);
|
|
||||||
|
|
||||||
// traffic priority -> TC0
|
|
||||||
WriteValue = 0;
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, HDA_OFFSET_PCIE_TCSEL, (void *)&WriteValue, 1, 0, EfiPciWidthUint8);
|
|
||||||
|
|
||||||
AllocateRIRBBuffer(PcieDeviceConfigSpace);
|
|
||||||
AllocateCORBBuffer(PcieDeviceConfigSpace);
|
|
||||||
|
|
||||||
// Turn all nodes on
|
|
||||||
SendCommandToAllWidgets8BitPayload(PcieDeviceConfigSpace, HDA_VRB_SET_POWER_STATE, 0x0);
|
|
||||||
|
|
||||||
// Set initial volume to output widgets
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0x0, 0x10, HDA_VRB_SET_AMPLIFIER_GAIN_MUTE, INITIAL_VOLUME, &Response);
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0x0, 0x11, HDA_VRB_SET_AMPLIFIER_GAIN_MUTE, INITIAL_VOLUME, &Response);
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS AllocateResourcesBasedOnFile(PCI_HDA_REGION *PcieDeviceConfigSpace, HDA_CONTROLLER_REGISTER_SET *ControllerRegisterSet, EFI_UINTN FileSize, EFI_UINTN DataAddress)
|
|
||||||
{
|
|
||||||
uint8_t WriteValue8 = 0;
|
|
||||||
uint16_t WriteValue16 = 0;
|
|
||||||
uint32_t WriteValue = 0;
|
|
||||||
uint32_t Response = 0;
|
|
||||||
|
|
||||||
void *AlignedDataMapping = NULL;
|
|
||||||
|
|
||||||
uint64_t BdlEntriesRequired = 0;
|
|
||||||
uint64_t BdlEntriesRequiredCurrentEntry = 0;
|
|
||||||
|
|
||||||
AllocateStreamsPages(PcieDeviceConfigSpace, ControllerRegisterSet);
|
|
||||||
if (SoundDataSize < 0xFFFFFFFF) {
|
|
||||||
BdlEntriesRequired = 1;
|
|
||||||
} else {
|
|
||||||
BdlEntriesRequired = SoundDataSize / 0xFFFFFFFF;
|
|
||||||
if (SoundDataSize % 0xFFFFFFFF > 0) {
|
|
||||||
BdlEntriesRequired += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (BdlEntriesRequiredCurrentEntry = 0; BdlEntriesRequiredCurrentEntry < 2; BdlEntriesRequiredCurrentEntry++) {
|
|
||||||
SetupCommonBuffer(&AlignedDataBufferBdlEntry, SoundDataSize / BdlEntriesRequired, &AlignedDataMapping, 2);
|
|
||||||
|
|
||||||
memcpy(AlignedDataBufferBdlEntry, SoundData, SoundDataSize / BdlEntriesRequired);
|
|
||||||
AddDescriptorListEntryOss0(PcieDeviceConfigSpace, ControllerRegisterSet, (uint64_t)AlignedDataBufferBdlEntry, SoundDataSize / BdlEntriesRequired, BdlEntriesRequiredCurrentEntry, BdlEntriesRequiredCurrentEntry + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write cyclic buffer length
|
|
||||||
WriteValue = SoundDataSize * 2;
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(0, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXCBL, (void *)&WriteValue, 1, 0, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
// Setup stream ID on codec nodes
|
|
||||||
WriteValue8 = 0x10;
|
|
||||||
GetCodecData8BitPayloadCorbRirb(PcieDeviceConfigSpace, 0, 0x10, HDA_VRB_SET_CHANNEL_STREAM_ID, WriteValue8, &Response);
|
|
||||||
|
|
||||||
// Set stream ID
|
|
||||||
WriteValue = 0x100000;
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(0, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXCTL, (void *)&WriteValue, 1, 0, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
// Set FIFO size
|
|
||||||
WriteValue = 0x04;
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(0, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXFIFOS, (void *)&WriteValue, 1, 0, EfiPciWidthUint32);
|
|
||||||
|
|
||||||
// Set stream format (2 channel, 16 bits, 44.1kHz)
|
|
||||||
WriteValue16 = 0x4011;
|
|
||||||
GetCodecData16BitPayloadCorbRirb(PcieDeviceConfigSpace, 0x0, 0x11, HDA_VRB_SET_STREAM_FORMAT, WriteValue16, &Response);
|
|
||||||
WriteControllerRegister(PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(0, ControllerRegisterSet->GCAP) + HDA_RELATIVE_OFFSET_SDXFMT, (void *)&WriteValue16, 1, 0, EfiPciWidthUint16);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS uefi_entry(EFI_HANDLE ImageHandle,
|
EFI_STATUS uefi_entry(EFI_HANDLE ImageHandle,
|
||||||
EFI_SYSTEM_TABLE *SystemTable)
|
EFI_SYSTEM_TABLE *SystemTable)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
EFI_GUID spp_guid = EFI_SIMPLE_POINTER_PROTOCOL_GUID;
|
||||||
|
EFI_SIMPLE_POINTER_PROTOCOL *spp[5];
|
||||||
|
|
||||||
gImageHandle = ImageHandle;
|
gImageHandle = ImageHandle;
|
||||||
gSystemTable = SystemTable;
|
gSystemTable = SystemTable;
|
||||||
|
@ -136,29 +60,33 @@ EFI_STATUS uefi_entry(EFI_HANDLE ImageHandle,
|
||||||
debug("Couldn't disable UEFI watchdog: %s (%x)\n", efi_status_to_str(Status), Status);
|
debug("Couldn't disable UEFI watchdog: %s (%x)\n", efi_status_to_str(Status), Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
// load Intel HDA driver
|
// load that mouse up
|
||||||
HDA_CONTROLLER_REGISTER_SET ControllerRegisterSet;
|
EFI_UINTN spp_handles = 0;
|
||||||
PCI_HDA_REGION PcieDeviceConfigSpace;
|
EFI_HANDLE *spp_handle_buf = NULL;
|
||||||
uint32_t WriteValue = 0;
|
Status = gBootServices->LocateHandleBuffer(ByProtocol, &spp_guid, NULL, &spp_handles, &spp_handle_buf);
|
||||||
uint16_t CurrentVolume = 12;
|
|
||||||
|
|
||||||
SoundData = chime_data;
|
|
||||||
SoundDataSize = chime_len;
|
|
||||||
|
|
||||||
Status = InitHda();
|
|
||||||
if (EFI_ERROR(Status)) {
|
if (EFI_ERROR(Status)) {
|
||||||
debug("uefi_entry(): Failed to initialize HDA driver!\n");
|
debug("uefi_entry(): Failed to locate Simple Pointer Protocol handle buffer: %s (%x).", efi_status_to_str(Status), Status);
|
||||||
} else {
|
} else {
|
||||||
Status = GetPcieConfigSpace(HDA_BUS, HDA_DEV, HDA_FUNC, &PcieDeviceConfigSpace);
|
debug("uefi_entry(): Found %u handle%s\n", spp_handles, spp_handles == 1 ? "" : "s");
|
||||||
|
for (EFI_UINTN i = 0; i < spp_handles; i++) {
|
||||||
|
Status = gBootServices->OpenProtocol(spp_handle_buf[i], &spp_guid, (void **)&spp[i], gImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
||||||
if (EFI_ERROR(Status)) {
|
if (EFI_ERROR(Status)) {
|
||||||
debug("uefi_entry(): Failed to initialize HDA driver!\n");
|
debug("uefi_entry(): Failed to open Simple Pointer Protocol on handle: %s (%x)\n", efi_status_to_str(Status), Status);
|
||||||
} else {
|
continue;
|
||||||
GetControllerRegisterSet(&PcieDeviceConfigSpace, &ControllerRegisterSet);
|
}
|
||||||
InitHdaControllerCodecAndBuffers(&PcieDeviceConfigSpace, &ControllerRegisterSet);
|
|
||||||
AllocateResourcesBasedOnFile(&PcieDeviceConfigSpace, &ControllerRegisterSet, 0, 0);
|
|
||||||
|
|
||||||
WriteValue = 0x100002;
|
debug("Found SPP with ResX=%u, ResY=%u\n", spp[i]->Mode->ResolutionX, spp[i]->Mode->ResolutionY);
|
||||||
WriteControllerRegister(&PcieDeviceConfigSpace, CALCULATE_OSSN_OFFSET(0, ControllerRegisterSet.GCAP) + HDA_RELATIVE_OFFSET_SDXCTL, (void *)&WriteValue, 1, 0, EfiPciWidthUint32);
|
if (spp[i]->Reset(spp[i], EFI_TRUE) == EFI_DEVICE_ERROR) {
|
||||||
|
debug("uefi_entry(): Failed to reset device\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spp[i]->Mode->ResolutionX < 65536) {
|
||||||
|
gPointerProtocol = spp[i];
|
||||||
|
mouse_resx = spp[i]->Mode->ResolutionX;
|
||||||
|
mouse_resy = spp[i]->Mode->ResolutionY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,15 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
bool get_framebuffer(uintptr_t *fb_addr, struct fb_mode **available_modes, int *total_modes, int *current_mode_index)
|
bool get_framebuffer(uint32_t **fb_addr, struct fb_mode **available_modes, int *total_modes, int *current_mode_index)
|
||||||
{
|
{
|
||||||
EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
|
||||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info = NULL;
|
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info = NULL;
|
||||||
EFI_UINTN mode_info_size = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
|
EFI_UINTN mode_info_size = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
|
||||||
EFI_UINTN SizeOfInfo, numModes, nativeMode;
|
EFI_UINTN SizeOfInfo;
|
||||||
|
EFI_UINTN numModes = 0;
|
||||||
|
EFI_UINTN nativeMode = 0;
|
||||||
EFI_UINTN mode_index = 0;
|
EFI_UINTN mode_index = 0;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
@ -45,10 +47,9 @@ bool get_framebuffer(uintptr_t *fb_addr, struct fb_mode **available_modes, int *
|
||||||
// this is needed to get the current video mode
|
// this is needed to get the current video mode
|
||||||
if (Status == EFI_NOT_STARTED) {
|
if (Status == EFI_NOT_STARTED) {
|
||||||
Status = gop->SetMode(gop, 0);
|
Status = gop->SetMode(gop, 0);
|
||||||
}
|
} else if (EFI_ERROR(Status)) {
|
||||||
|
|
||||||
if (EFI_ERROR(Status)) {
|
|
||||||
debug("Unable to get native mode\n");
|
debug("Unable to get native mode\n");
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
nativeMode = gop->Mode->Mode;
|
nativeMode = gop->Mode->Mode;
|
||||||
numModes = gop->Mode->MaxMode;
|
numModes = gop->Mode->MaxMode;
|
||||||
|
@ -57,10 +58,10 @@ bool get_framebuffer(uintptr_t *fb_addr, struct fb_mode **available_modes, int *
|
||||||
*total_modes = numModes;
|
*total_modes = numModes;
|
||||||
*available_modes = (struct fb_mode *)mem_alloc(sizeof(struct fb_mode) * numModes);
|
*available_modes = (struct fb_mode *)mem_alloc(sizeof(struct fb_mode) * numModes);
|
||||||
|
|
||||||
*fb_addr = gop->Mode->FrameBufferBase;
|
*fb_addr = (uint32_t *)gop->Mode->FrameBufferBase;
|
||||||
|
|
||||||
// get all available modes
|
// get all available modes
|
||||||
for (int i = 0; i < numModes; i++) {
|
for (int i = 0; i < (int)numModes; i++) {
|
||||||
Status = gop->QueryMode(gop, i, &SizeOfInfo, &mode_info);
|
Status = gop->QueryMode(gop, i, &SizeOfInfo, &mode_info);
|
||||||
|
|
||||||
(*available_modes)[i].width = mode_info->HorizontalResolution;
|
(*available_modes)[i].width = mode_info->HorizontalResolution;
|
||||||
|
@ -77,7 +78,7 @@ bool get_framebuffer(uintptr_t *fb_addr, struct fb_mode **available_modes, int *
|
||||||
(*available_modes)[i].format = FB_BGRA;
|
(*available_modes)[i].format = FB_BGRA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == nativeMode) {
|
if (i == (int)nativeMode) {
|
||||||
*current_mode_index = i;
|
*current_mode_index = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
45
boot/platform/uefi/ui/mouse.c
Normal file
45
boot/platform/uefi/ui/mouse.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*********************************************************************************/
|
||||||
|
/* Module Name: mouse.c */
|
||||||
|
/* Project: AurixOS */
|
||||||
|
/* */
|
||||||
|
/* Copyright (c) 2024-2025 Jozef Nagy */
|
||||||
|
/* */
|
||||||
|
/* This source is subject to the MIT License. */
|
||||||
|
/* See License.txt in the root of this repository. */
|
||||||
|
/* All other rights reserved. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
|
||||||
|
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
|
||||||
|
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
|
||||||
|
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
|
||||||
|
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
|
||||||
|
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
|
||||||
|
/* SOFTWARE. */
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
#include <ui/ui.h>
|
||||||
|
#include <ui/mouse.h>
|
||||||
|
#include <efi.h>
|
||||||
|
#include <efilib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern EFI_SIMPLE_POINTER_PROTOCOL *gPointerProtocol;
|
||||||
|
extern uint16_t mouse_resx;
|
||||||
|
extern uint16_t mouse_resy;
|
||||||
|
|
||||||
|
void get_mouse(uint16_t *mouse_x, uint16_t *mouse_y, uint8_t *mouse_buttons)
|
||||||
|
{
|
||||||
|
if (!gPointerProtocol) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*mouse_buttons = 0;
|
||||||
|
EFI_SIMPLE_POINTER_STATE state;
|
||||||
|
gPointerProtocol->GetState(gPointerProtocol, &state);
|
||||||
|
|
||||||
|
*mouse_buttons |= state.LeftButton ? LEFT_MOUSE_BUTTON : 0;
|
||||||
|
*mouse_buttons |= state.RightButton ? RIGHT_MOUSE_BUTTON : 0;
|
||||||
|
|
||||||
|
*mouse_x += state.RelativeMovementX / mouse_resx;
|
||||||
|
*mouse_y += state.RelativeMovementY / mouse_resy;
|
||||||
|
}
|
|
@ -13,12 +13,10 @@ tempmountdir=$(mktemp -d 2>/dev/null)
|
||||||
# Create UEFI image
|
# Create UEFI image
|
||||||
dd if=/dev/zero of=$uefi_image bs=1k count=1440 >/dev/null 2>&1
|
dd if=/dev/zero of=$uefi_image bs=1k count=1440 >/dev/null 2>&1
|
||||||
mformat -i $uefi_image -f 1440 :: >/dev/null 2>&1
|
mformat -i $uefi_image -f 1440 :: >/dev/null 2>&1
|
||||||
mmd -i $uefi_image ::/EFI >/dev/null 2>&1
|
|
||||||
mmd -i $uefi_image ::/EFI/BOOT >/dev/null 2>&1
|
|
||||||
mcopy -i $uefi_image $SYSROOT_DIR/EFI/BOOT/BOOTX64.EFI ::/EFI/BOOT >/dev/null 2>&1
|
|
||||||
## !FIXME: Huge hack! Make a filesystem.
|
## !FIXME: Huge hack! Make a filesystem.
|
||||||
mmd -i $uefi_image ::/System >/dev/null 2>&1
|
mcopy -i $uefi_image -s $SYSROOT_DIR/EFI :: >/dev/null 2>&1
|
||||||
mcopy -i $uefi_image $SYSROOT_DIR/System/axkrnl ::/System >/dev/null 2>&1
|
mcopy -i $uefi_image -s $SYSROOT_DIR/System :: >/dev/null 2>&1
|
||||||
|
mcopy -i $uefi_image -s $SYSROOT_DIR/AxBoot :: >/dev/null 2>&1
|
||||||
|
|
||||||
# Create directory structure
|
# Create directory structure
|
||||||
mkdir -p $tempmountdir/boot
|
mkdir -p $tempmountdir/boot
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue