update bdk

Signed-off-by: Damien Zhao <zdm65477730@126.com>
This commit is contained in:
Damien Zhao
2023-02-25 00:33:58 +08:00
parent 06d55e6d87
commit cf553f87dd
129 changed files with 7997 additions and 5104 deletions

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2022 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -18,8 +18,8 @@
#include "btn.h"
#include <soc/i2c.h>
#include <soc/gpio.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <utils/util.h>
#include <power/max77620.h>
u8 btn_read()
@@ -29,6 +29,7 @@ u8 btn_read()
res |= BTN_VOL_DOWN;
if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6))
res |= BTN_VOL_UP;
// HOAG can use the GPIO. Icosa/Iowa/AULA cannot. Traces are there but they miss a resistor.
if (i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFSTAT) & MAX77620_ONOFFSTAT_EN0)
res |= BTN_POWER;
return res;
@@ -44,6 +45,11 @@ u8 btn_read_vol()
return res;
}
u8 btn_read_home()
{
return (!gpio_read(GPIO_PORT_Y, GPIO_PIN_1)) ? BTN_HOME : 0;
}
u8 btn_wait()
{
u8 res = 0, btn = btn_read();

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2022 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -23,10 +23,12 @@
#define BTN_POWER BIT(0)
#define BTN_VOL_DOWN BIT(1)
#define BTN_VOL_UP BIT(2)
#define BTN_HOME BIT(3)
#define BTN_SINGLE BIT(7)
u8 btn_read();
u8 btn_read_vol();
u8 btn_read_home();
u8 btn_wait();
u8 btn_wait_timeout(u32 time_ms, u8 mask);
u8 btn_wait_timeout_single(u32 time_ms, u8 mask);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018-2022 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -21,25 +21,7 @@
#include <libs/fatfs/ff.h>
#include <mem/heap.h>
#include <utils/dirlist.h>
static char *_strdup(char *str)
{
if (!str)
return NULL;
// Remove starting space.
if (str[0] == ' ' && strlen(str))
str++;
char *res = (char *)malloc(strlen(str) + 1);
strcpy(res, str);
// Remove trailing space.
if (strlen(res) && res[strlen(res) - 1] == ' ')
res[strlen(res) - 1] = 0;
return res;
}
#include <utils/util.h>
u32 _find_section_name(char *lbuf, u32 lblen, char schar)
{
@@ -57,23 +39,30 @@ ini_sec_t *_ini_create_section(link_t *dst, ini_sec_t *csec, char *name, u8 type
if (csec)
list_append(dst, &csec->link);
csec = (ini_sec_t *)calloc(sizeof(ini_sec_t), 1);
csec->name = _strdup(name);
// Calculate total allocation size.
u32 len = name ? strlen(name) + 1 : 0;
char *buf = calloc(sizeof(ini_sec_t) + len, 1);
csec = (ini_sec_t *)buf;
csec->name = strcpy_ns(buf + sizeof(ini_sec_t), name);
csec->type = type;
// Initialize list.
list_init(&csec->kvs);
return csec;
}
int ini_parse(link_t *dst, char *ini_path, bool is_dir)
{
u32 lblen;
u32 pathlen = strlen(ini_path);
u32 k = 0;
char lbuf[512];
char *filelist = NULL;
FIL fp;
u32 lblen;
u32 k = 0;
u32 pathlen = strlen(ini_path);
ini_sec_t *csec = NULL;
char *lbuf = NULL;
char *filelist = NULL;
char *filename = (char *)malloc(256);
strcpy(filename, ini_path);
@@ -114,8 +103,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
return 0;
}
csec = _ini_create_section(dst, csec, "Unknown", INI_CHOICE);
list_init(&csec->kvs);
lbuf = malloc(512);
do
{
@@ -133,7 +121,6 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
_find_section_name(lbuf, lblen, ']');
csec = _ini_create_section(dst, csec, &lbuf[1], INI_CHOICE);
list_init(&csec->kvs);
}
else if (lblen > 1 && lbuf[0] == '{') // Create new caption. Support empty caption '{}'.
{
@@ -154,13 +141,22 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
{
u32 i = _find_section_name(lbuf, lblen, '=');
ini_kv_t *kv = (ini_kv_t *)calloc(sizeof(ini_kv_t), 1);
kv->key = _strdup(&lbuf[0]);
kv->val = _strdup(&lbuf[i + 1]);
// Calculate total allocation size.
u32 klen = strlen(&lbuf[0]) + 1;
u32 vlen = strlen(&lbuf[i + 1]) + 1;
char *buf = calloc(sizeof(ini_kv_t) + klen + vlen, 1);
ini_kv_t *kv = (ini_kv_t *)buf;
buf += sizeof(ini_kv_t);
kv->key = strcpy_ns(buf, &lbuf[0]);
buf += klen;
kv->val = strcpy_ns(buf, &lbuf[i + 1]);
list_append(&csec->kvs, &kv->link);
}
} while (!f_eof(&fp));
free(lbuf);
f_close(&fp);
if (csec)
@@ -177,16 +173,55 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
return 1;
}
char *ini_check_payload_section(ini_sec_t *cfg)
char *ini_check_special_section(ini_sec_t *cfg)
{
if (cfg == NULL)
return NULL;
LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link)
{
if (!strcmp("payload", kv->key))
if (!strcmp("l4t", kv->key))
return ((kv->val[0] == '1') ? (char *)-1 : NULL);
else if (!strcmp("payload", kv->key))
return kv->val;
}
return NULL;
}
void ini_free(link_t *src)
{
ini_sec_t *prev_sec = NULL;
// Parse and free all ini sections.
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, src, link)
{
ini_kv_t *prev_kv = NULL;
// Free all ini key allocations if they exist.
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
{
// Free previous key.
if (prev_kv)
free(prev_kv);
// Set next key to free.
prev_kv = kv;
}
// Free last key.
if (prev_kv)
free(prev_kv);
// Free previous section.
if (prev_sec)
free(prev_sec);
// Set next section to free.
prev_sec = ini_sec;
}
// Free last section.
if (prev_sec)
free(prev_sec);
}

View File

@@ -43,8 +43,9 @@ typedef struct _ini_sec_t
u32 color;
} ini_sec_t;
int ini_parse(link_t *dst, char *ini_path, bool is_dir);
char *ini_check_payload_section(ini_sec_t *cfg);
int ini_parse(link_t *dst, char *ini_path, bool is_dir);
char *ini_check_special_section(ini_sec_t *cfg);
void ini_free(link_t *src);
#endif

View File

@@ -28,16 +28,25 @@
/*! Iterate over all list links. */
#define LIST_FOREACH(iter, list) \
for(link_t *iter = (list)->next; iter != (list); iter = iter->next)
for (link_t *iter = (list)->next; iter != (list); iter = iter->next)
/*! Iterate over all list links backwards. */
#define LIST_FOREACH_INVERSE(iter, list) \
for (link_t *iter = (list)->prev; iter != (list); iter = iter->prev)
/*! Safely iterate over all list links. */
#define LIST_FOREACH_SAFE(iter, list) \
for(link_t *iter = (list)->next, *safe = iter->next; iter != (list); iter = safe, safe = iter->next)
for (link_t *iter = (list)->next, *safe = iter->next; iter != (list); iter = safe, safe = iter->next)
/*! Iterate over all list members and make sure that the list has at least one entry. */
#define LIST_FOREACH_ENTRY(etype, iter, list, mn) \
if ((list)->next != (list)) \
for(etype *iter = CONTAINER_OF((list)->next, etype, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.next, etype, mn))
for (etype *iter = CONTAINER_OF((list)->next, etype, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.next, etype, mn))
/* Iterate over all list members backwards and make sure that the list has at least one entry. */
#define LIST_FOREACH_ENTRY_INVERSE(type, iter, list, mn) \
if ((list)->prev != (list)) \
for (type *iter = CONTAINER_OF((list)->prev, type, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.prev, type, mn))
typedef struct _link_t
{
@@ -53,7 +62,7 @@ static inline void link_init(link_t *l)
static inline int link_used(link_t *l)
{
if(l->next == NULL)
if (l->next == NULL)
return 1;
return 0;
}
@@ -89,7 +98,7 @@ static inline void list_remove(link_t *l)
static inline int list_empty(link_t *lh)
{
if(lh->next == lh)
if (lh->next == lh)
return 1;
return 0;
}

View File

@@ -1,123 +1,214 @@
/*
* Copyright (c) 2019-2020 shchmue
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "sprintf.h"
* Copyright (c) 2018 naehrwert
* Copyright (c) 2019-2022 CTCaer
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <stdarg.h>
#include <string.h>
static void _putc(char *buffer, const char c) {
*buffer = c;
#include <utils/types.h>
char **sout_buf;
static void _s_putc(char c)
{
**sout_buf = c;
*sout_buf += 1;
}
static u32 _puts(char *buffer, const char *s) {
u32 count = 0;
for (; *s; s++, count++)
_putc(buffer + count, *s);
return count;
static void _s_puts(char *s)
{
for (; *s; s++)
_s_putc(*s);
}
static u32 _putn(char *buffer, u32 v, int base, char fill, int fcnt) {
char buf[0x121];
static const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
char *p;
int c = fcnt;
static void _s_putn(u32 v, int base, char fill, int fcnt)
{
static const char digits[] = "0123456789ABCDEF";
if (base > 36)
return 0;
char *p;
char buf[65];
int c = fcnt;
bool negative = false;
p = buf + 0x120;
*p = 0;
do {
c--;
*--p = digits[v % base];
v /= base;
} while (v);
if (base != 10 && base != 16)
return;
if (fill != 0) {
while (c > 0) {
*--p = fill;
c--;
}
}
// Account for negative numbers.
if (base == 10 && v & 0x80000000)
{
negative = true;
v = (int)v * -1;
c--;
}
return _puts(buffer, p);
p = buf + 64;
*p = 0;
do
{
c--;
*--p = digits[v % base];
v /= base;
} while (v);
if (negative)
*--p = '-';
if (fill != 0)
{
while (c > 0 && p > buf)
{
*--p = fill;
c--;
}
}
_s_puts(p);
}
u32 s_printf(char *buffer, const char *fmt, ...) {
va_list ap;
int fill, fcnt;
u32 count = 0;
void s_printf(char *out_buf, const char *fmt, ...)
{
va_list ap;
int fill, fcnt;
va_start(ap, fmt);
while(*fmt) {
if (*fmt == '%') {
fmt++;
fill = 0;
fcnt = 0;
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ') {
fcnt = *fmt;
fmt++;
if (*fmt >= '0' && *fmt <= '9') {
fill = fcnt;
fcnt = *fmt - '0';
fmt++;
} else {
fill = ' ';
fcnt -= '0';
}
}
switch (*fmt) {
case 'c':
_putc(buffer + count, va_arg(ap, u32));
count++;
break;
case 's':
count += _puts(buffer + count, va_arg(ap, char *));
break;
case 'd':
count += _putn(buffer + count, va_arg(ap, u32), 10, fill, fcnt);
break;
case 'p':
case 'P':
case 'x':
case 'X':
count += _putn(buffer + count, va_arg(ap, u32), 16, fill, fcnt);
break;
case '%':
_putc(buffer + count, '%');
count++;
break;
case '\0':
goto out;
default:
_putc(buffer + count, '%');
count++;
_putc(buffer + count, *fmt);
count++;
break;
}
} else {
_putc(buffer + count, *fmt);
count++;
}
fmt++;
}
sout_buf = &out_buf;
out:
buffer[count] = 0;
va_end(ap);
return count;
}
va_start(ap, fmt);
while (*fmt)
{
if (*fmt == '%')
{
fmt++;
fill = 0;
fcnt = 0;
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')
{
fcnt = *fmt;
fmt++;
if (*fmt >= '0' && *fmt <= '9')
{
fill = fcnt;
fcnt = *fmt - '0';
fmt++;
}
else
{
fill = ' ';
fcnt -= '0';
}
}
switch (*fmt)
{
case 'c':
_s_putc(va_arg(ap, u32));
break;
case 's':
_s_puts(va_arg(ap, char *));
break;
case 'd':
_s_putn(va_arg(ap, u32), 10, fill, fcnt);
break;
case 'p':
case 'P':
case 'x':
case 'X':
_s_putn(va_arg(ap, u32), 16, fill, fcnt);
break;
case '%':
_s_putc('%');
break;
case '\0':
goto out;
default:
_s_putc('%');
_s_putc(*fmt);
break;
}
}
else
_s_putc(*fmt);
fmt++;
}
out:
**sout_buf = '\0';
va_end(ap);
}
void s_vprintf(char *out_buf, const char *fmt, va_list ap)
{
int fill, fcnt;
sout_buf = &out_buf;
while (*fmt)
{
if (*fmt == '%')
{
fmt++;
fill = 0;
fcnt = 0;
if ((*fmt >= '0' && *fmt <= '9') || *fmt == ' ')
{
fcnt = *fmt;
fmt++;
if (*fmt >= '0' && *fmt <= '9')
{
fill = fcnt;
fcnt = *fmt - '0';
fmt++;
}
else
{
fill = ' ';
fcnt -= '0';
}
}
switch(*fmt)
{
case 'c':
_s_putc(va_arg(ap, u32));
break;
case 's':
_s_puts(va_arg(ap, char *));
break;
case 'd':
_s_putn(va_arg(ap, u32), 10, fill, fcnt);
break;
case 'p':
case 'P':
case 'x':
case 'X':
_s_putn(va_arg(ap, u32), 16, fill, fcnt);
break;
case '%':
_s_putc('%');
break;
case '\0':
goto out;
default:
_s_putc('%');
_s_putc(*fmt);
break;
}
}
else
_s_putc(*fmt);
fmt++;
}
out:
**sout_buf = '\0';
}

View File

@@ -1,24 +1,27 @@
/*
* Copyright (c) 2019-2020 shchmue
*
* 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 <http://www.gnu.org/licenses/>.
*/
* Copyright (c) 2019 CTCaer
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef _SPRINTF_H_
#define _SPRINTF_H_
#include "types.h"
#include <stdarg.h>
u32 s_printf(char *buffer, const char *fmt, ...);
#include <utils/types.h>
#endif
void s_printf(char *out_buf, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
void s_vprintf(char *out_buf, const char *fmt, va_list ap);
#endif

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2021 CTCaer
* Copyright (c) 2018-2022 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -56,9 +56,9 @@ typedef volatile unsigned short vu16;
typedef volatile unsigned int vu32;
#ifdef __aarch64__
typedef u64 uptr;
typedef unsigned long long uptr;
#else /* __arm__ or __thumb__ */
typedef u32 uptr;
typedef unsigned long uptr;
#endif
static const u32 colors[6] = {COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_GREEN, COLOR_BLUE, COLOR_VIOLET};
@@ -113,7 +113,7 @@ static const u32 colors[6] = {COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_GREEN
#define byte_swap_16(num) ((((num) >> 8) & 0xff) | (((num) << 8) & 0xff00))
#define byte_swap_32(num) ((((num) >> 24) & 0xff) | (((num) << 8) & 0xff0000) | \
(((num) >> 8 )& 0xff00) | (((num) << 24) & 0xff000000))
(((num) >> 8 ) & 0xff00) | (((num) << 24) & 0xff000000))
/* Bootloader/Nyx */
@@ -153,8 +153,8 @@ typedef struct __attribute__((__packed__)) _boot_cfg_t
{
struct
{
char id[8]; // 7 char ASCII null teminated.
char emummc_path[0x78]; // emuMMC/XXX, ASCII null teminated.
char id[8]; // 7 char ASCII null terminated.
char emummc_path[0x78]; // emuMMC/XXX, ASCII null terminated.
};
u8 ums; // nyx_ums_type.
u8 xt_str[0x80];

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018-2022 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -15,7 +15,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <utils/util.h>
#include <string.h>
#include <mem/heap.h>
#include <power/max77620.h>
#include <rtc/max77620-rtc.h>
@@ -23,13 +24,13 @@
#include <soc/hw_init.h>
#include <soc/i2c.h>
#include <soc/pmc.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <storage/nx_sd.h>
#include <storage/sd.h>
#include <utils/util.h>
#define USE_RTC_TIMER
extern volatile nyx_storage_t *nyx_str;
u8 bit_count(u32 val)
{
u8 cnt = 0;
@@ -51,54 +52,153 @@ u32 bit_count_mask(u8 bits)
return val;
}
u32 get_tmr_s()
char *strcpy_ns(char *dst, char *src)
{
return RTC(APBDEV_RTC_SECONDS);
if (!src || !dst)
return NULL;
// Remove starting space.
u32 len = strlen(src);
if (len && src[0] == ' ')
{
len--;
src++;
}
strcpy(dst, src);
// Remove trailing space.
if (len && dst[len - 1] == ' ')
dst[len - 1] = 0;
return dst;
}
u32 get_tmr_ms()
// Approximate square root finder for a 64-bit number.
u64 sqrt64(u64 num)
{
// The registers must be read with the following order:
// RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC)
return (RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000));
u64 base = 0;
u64 limit = num;
u64 square_root = 0;
while (base <= limit)
{
u64 tmp_sqrt = (base + limit) / 2;
if (tmp_sqrt * tmp_sqrt == num) {
square_root = tmp_sqrt;
break;
}
if (tmp_sqrt * tmp_sqrt < num)
{
square_root = base;
base = tmp_sqrt + 1;
}
else
limit = tmp_sqrt - 1;
}
return square_root;
}
u32 get_tmr_us()
#define TLONG_MAX ((long)(((unsigned long)(~0L)) >> 1))
#define TLONG_MIN ((long)(~TLONG_MAX))
#define ISSPACE(ch) ((ch >= '\t' && ch <= '\r') || (ch == ' '))
#define ISDIGIT(ch) ( ch >= '0' && ch <= '9' )
#define ISALPHA(ch) ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
#define ISUPPER(ch) ( ch >= 'A' && ch <= 'Z' )
/*
* Avoid using reentrant newlib version of strol. It's only used for errno.
*
* strol/atoi:
* Copyright (c) 1990 The Regents of the University of California.
*/
long strtol(const char *nptr, char **endptr, register int base)
{
return TMR(TIMERUS_CNTR_1US);
register const char *s = nptr;
register unsigned long acc;
register int c;
register unsigned long cutoff;
register int neg = 0, any, cutlim;
/*
* Skip white space and pick up leading +/- sign if any.
* If base is 0, allow 0x for hex and 0 for octal, else
* assume decimal; if base is already 16, allow 0x.
*/
do {
c = *s++;
} while (ISSPACE(c));
if (c == '-') {
neg = 1;
c = *s++;
} else if (c == '+')
c = *s++;
if ((base == 0 || base == 16) &&
c == '0' && (*s == 'x' || *s == 'X')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
/*
* Compute the cutoff value between legal numbers and illegal
* numbers. That is the largest legal value, divided by the
* base. An input number that is greater than this value, if
* followed by a legal input character, is too big. One that
* is equal to this value may be valid or not; the limit
* between valid and invalid numbers is then based on the last
* digit. For instance, if the range for longs is
* [-2147483648..2147483647] and the input base is 10,
* cutoff will be set to 214748364 and cutlim to either
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
* a value > 214748364, or equal but the next digit is > 7 (or 8),
* the number is too big, and we will return a range error.
*
* Set any if any `digits' consumed; make it negative to indicate
* overflow.
*/
cutoff = neg ? -(unsigned long)TLONG_MIN : TLONG_MAX;
cutlim = cutoff % (unsigned long)base;
cutoff /= (unsigned long)base;
for (acc = 0, any = 0;; c = *s++) {
if (ISDIGIT(c))
c -= '0';
else if (ISALPHA(c))
c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
any = -1;
else {
any = 1;
acc *= base;
acc += c;
}
}
if (any < 0) {
acc = neg ? TLONG_MIN : TLONG_MAX;
} else if (neg)
acc = -acc;
if (endptr != 0)
*endptr = (char *) (any ? s - 1 : nptr);
return (acc);
}
void msleep(u32 ms)
int atoi(const char *nptr)
{
#ifdef USE_RTC_TIMER
u32 start = RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000);
// Casting to u32 is important!
while (((u32)(RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000)) - start) <= ms)
;
#else
bpmp_msleep(ms);
#endif
}
void usleep(u32 us)
{
#ifdef USE_RTC_TIMER
u32 start = TMR(TIMERUS_CNTR_1US);
// Check if timer is at upper limits and use BPMP sleep so it doesn't wake up immediately.
if ((start + us) < start)
bpmp_usleep(us);
else
while ((u32)(TMR(TIMERUS_CNTR_1US) - start) <= us) // Casting to u32 is important!
;
#else
bpmp_usleep(us);
#endif
return (int)strtol(nptr, (char **)NULL, 10);
}
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops)
{
for(u32 i = 0; i < num_ops; i++)
for (u32 i = 0; i < num_ops; i++)
base[ops[i].off] = ops[i].val;
}
@@ -143,14 +243,14 @@ void panic(u32 val)
{
// Set panic code.
PMC(APBDEV_PMC_SCRATCH200) = val;
//PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_DISABLE;
TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN;
TMR(TIMER_TMR9_TMR_PTV) = TIMER_EN | TIMER_PER_EN;
TMR(TIMER_WDT4_CONFIG) = TIMER_SRC(9) | TIMER_PER(1) | TIMER_PMCRESET_EN;
TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT;
while (true)
usleep(1);
// Disable SE.
//PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_DISABLE;
// Immediately cause a full system reset.
watchdog_start(0, TIMER_PMCRESET_EN);
while (true);
}
void power_set_state(power_state_t state)
@@ -179,7 +279,7 @@ void power_set_state(power_state_t state)
break;
case POWER_OFF:
// Initiate power down sequence and do not generate a reset (regulators retain state).
// Initiate power down sequence and do not generate a reset (regulators retain state after POR).
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF);
break;
@@ -194,7 +294,7 @@ void power_set_state(power_state_t state)
reg |= MAX77620_ONOFFCNFG2_SFT_RST_WK;
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2, reg);
// Initiate power down sequence and generate a reset (regulators' state resets).
// Initiate power down sequence and generate a reset (regulators' state resets after POR).
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_SFT_RST);
break;
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2021 CTCaer
* Copyright (c) 2018-2022 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -21,6 +21,8 @@
#include <utils/types.h>
#include <mem/minerva.h>
#define CFG_SIZE(array) (sizeof(array) / sizeof(cfg_op_t))
#define NYX_NEW_INFO 0x3058594E
typedef enum
@@ -35,9 +37,8 @@ typedef enum
typedef enum
{
NYX_CFG_BIS = BIT(5),
NYX_CFG_UMS = BIT(6),
NYX_CFG_DUMP = BIT(7),
NYX_CFG_EXTRA = 0xFF << 24
} nyx_cfg_t;
@@ -52,11 +53,6 @@ typedef enum
ERR_EXCEPTION = BIT(31),
} hekate_errors_t;
#define byte_swap_32(num) ((((num) >> 24) & 0xff) | (((num) << 8) & 0xff0000) | \
(((num) >> 8 )& 0xff00) | (((num) << 24) & 0xff000000))
#define byte_swap_16(num) ((((num) >> 8) & 0xff) | (((num) << 8) & 0xff00))
typedef struct _cfg_op_t
{
u32 off;
@@ -82,21 +78,19 @@ typedef struct _nyx_storage_t
u8 rsvd[SZ_8M - sizeof(nyx_info_t)];
nyx_info_t info;
mtc_config_t mtc_cfg;
emc_table_t mtc_table[10];
emc_table_t mtc_table[11]; // 10 + 1.
} nyx_storage_t;
u8 bit_count(u32 val);
u32 bit_count_mask(u8 bits);
char *strcpy_ns(char *dst, char *src);
u64 sqrt64(u64 num);
long strtol(const char *nptr, char **endptr, register int base);
int atoi(const char *nptr);
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
u32 crc32_calc(u32 crc, const u8 *buf, u32 len);
u32 get_tmr_us();
u32 get_tmr_ms();
u32 get_tmr_s();
void usleep(u32 us);
void msleep(u32 ms);
void panic(u32 val);
void power_set_state(power_state_t state);
void power_set_state_ex(void *param);