diff --git a/loader/heap.c b/loader/heap.c new file mode 100755 index 0000000..c90607b --- /dev/null +++ b/loader/heap.c @@ -0,0 +1,133 @@ +/* +* Copyright (c) 2018 naehrwert +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#include +#include "heap.h" + +typedef struct _hnode +{ + int used; + u32 size; + struct _hnode *prev; + struct _hnode *next; +} hnode_t; + +typedef struct _heap +{ + u32 start; + hnode_t *first; +} heap_t; + +static void _heap_create(heap_t *heap, u32 start) +{ + heap->start = start; + heap->first = NULL; +} + +static u32 _heap_alloc(heap_t *heap, u32 size) +{ + hnode_t *node, *new; + int search = 1; + + size = ALIGN(size, 0x10); + + if (!heap->first) + { + node = (hnode_t *)heap->start; + node->used = 1; + node->size = size; + node->prev = NULL; + node->next = NULL; + heap->first = node; + + return (u32)node + sizeof(hnode_t); + } + + node = heap->first; + while (search) + { + if (!node->used && size + sizeof(hnode_t) < node->size) + { + new = (hnode_t *)((u32)node + sizeof(hnode_t) + size); + + new->size = node->size - sizeof(hnode_t) - size; + node->size = size; + node->used = 1; + new->used = 0; + new->next = node->next; + new->prev = node; + node->next = new; + + return (u32)node + sizeof(hnode_t); + } + if (node->next) + node = node->next; + else + search = 0; + } + + new = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size); + new->used = 1; + new->size = size; + new->prev = node; + new->next = NULL; + node->next = new; + + return (u32)new + sizeof(hnode_t); +} + +static void _heap_free(heap_t *heap, u32 addr) +{ + hnode_t *node = (hnode_t *)(addr - sizeof(hnode_t)); + node->used = 0; + node = heap->first; + while (node) + { + if (!node->used) + if (node->prev && !node->prev->used) + { + node->prev->size += node->size + sizeof(hnode_t); + node->prev->next = node->next; + if (node->next) + node->next->prev = node->prev; + } + node = node->next; + } +} + +static heap_t _heap; + +void heap_init(u32 base) +{ + _heap_create(&_heap, base); +} + +void *malloc(u32 size) +{ + return (void *)_heap_alloc(&_heap, size); +} + +void *calloc(u32 num, u32 size) +{ + void *res = (void *)_heap_alloc(&_heap, num * size); + memset(res, 0, num * size); + return res; +} + +void free(void *buf) +{ + _heap_free(&_heap, (u32)buf); +} diff --git a/loader/heap.h b/loader/heap.h new file mode 100755 index 0000000..e1ab6fa --- /dev/null +++ b/loader/heap.h @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2018 naehrwert +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#ifndef _HEAP_H_ +#define _HEAP_H_ + +#include "types.h" + +void heap_init(u32 base); +void *malloc(u32 size); +void *calloc(u32 num, u32 size); +void free(void *buf); + +#endif diff --git a/loader/main.c b/loader/main.c index 2ca9763..52c30e7 100644 --- a/loader/main.c +++ b/loader/main.c @@ -29,6 +29,7 @@ #include "pinmux.h" #include "gpio.h" #include "i2c.h" +#include "uart.h" static inline u32 read32(uintptr_t addr) { return *(vu32 *)addr; @@ -62,30 +63,30 @@ void enter_rcm() { void config_hw(){ - printf_("Starting Initing hardware."); + printf_("Starting Initing hardware.\n"); fuse_disable_program(); printf_("[x] fuse program disabled\n"); - // Initialize counters, CLKM, BPMP(also called AVP in T124/T132) and other clocks based on 38.4MHz oscillator. + // Initialize oscillators config_oscillators(); + // My board didn't have UART port + // pinmux_config_uart(UART_D); + // clock_enable_uart(UART_D); + // uart_init(UART_D, 115200, UART_AO_TX_AO_RX); + // uart_invert(UART_D, 0, UART_INVERT_TXD); + + uart_send(UART_D, (u8 *)"hekate: Hello!\r\n", 16); + uart_wait_xfer(UART_D, UART_TX_IDLE); + mc_enable(); printf_("[x] mc setup\n"); config_gpios(); printf_("[x] GPIO setup\n"); - - //clock_enable_cl_dvfs(); - //printf_("[x] DVFS setup\n"); - - //FIXME I2C Doesn't work!!! - printf_("Fixme.I2C doesn't work"); - // clock_enable_i2c(I2C_1); - // clock_enable_i2c(I2C_5); - } - +extern void pivot_stack(u32 stack_top); __attribute__((section(".init"))) void _start() { // u8 *buffer = (u8*)0x40020000; @@ -98,6 +99,14 @@ void _start() { dump_pkc(); config_hw(); + //FIXME!!!->init memory + //Pivot the stack so we have enough space. +// pivot_stack(0x40000000); + + //Tegra/Horizon configuration goes to 0x80000000+, package2 goes to 0xA9800000, we place our heap in between. +// heap_init(0x90020000); + + enter_rcm(); } diff --git a/loader/mc.c b/loader/mc.c index e4c4962..c55ed4a 100644 --- a/loader/mc.c +++ b/loader/mc.c @@ -20,7 +20,25 @@ #include "util.h" #include "mc.h" +void mc_enable_ahb_redirect() +{ + CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) = CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) & 0xFFF7FFFF | 0x80000; + //MC(MC_IRAM_REG_CTRL) &= 0xFFFFFFFE; + MC(MC_IRAM_BOM) = 0x40000000; + MC(MC_IRAM_TOM) = 0x4003F000; +} + void mc_enable() { + CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) & 0x1FFFFFFF | 0x40000000; + //Enable MC clock. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) & 0xFFFFFFFE | 1; + //Enable EMC DLL clock. + CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) & 0xFFFFBFFF | 0x4000; + CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = 0x2000001; //Clear EMC and MC reset. + sleep(5); + + //Enable ahb redirect + mc_enable_ahb_redirect(); } \ No newline at end of file diff --git a/loader/mc.h b/loader/mc.h index 706f104..78b6217 100644 --- a/loader/mc.h +++ b/loader/mc.h @@ -15,4 +15,6 @@ * along with this program. If not, see . */ +#define MC_IRAM_BOM 0x65c +#define MC_IRAM_TOM 0x660 void mc_enable(); \ No newline at end of file diff --git a/loader/stack.S b/loader/stack.S new file mode 100644 index 0000000..cb91e74 --- /dev/null +++ b/loader/stack.S @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2018 naehrwert +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ +.globl pivot_stack +.type pivot_stack, %function +pivot_stack: + MOV SP, R0 + BX LR