diff --git a/Makefile b/Makefile
index 7508e24..4e61f0a 100644
--- a/Makefile
+++ b/Makefile
@@ -4,56 +4,57 @@ endif
include $(DEVKITARM)/base_rules
-IPL_LOAD_ADDR := 0x40003000
+################################################################################
-TARGET := Lockpick_RCM
+IPL_LOAD_ADDR := 0x40003000
LPVERSION_MAJOR := 1
LPVERSION_MINOR := 1
LPVERSION_BUGFX := 1
-BUILD := build
-OUTPUT := output
+################################################################################
+
+TARGET := Lockpick_RCM
+BUILDDIR := build
+OUTPUTDIR := output
SOURCEDIR = source
VPATH = $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
-OBJS = $(addprefix $(BUILD)/$(TARGET)/, \
+# Main and graphics.
+OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
start.o \
- main.o \
+ main.o heap.o \
keys.o \
- heap.o \
- btn.o \
- clock.o \
- cluster.o \
- fuse.o \
- gpio.o \
- sept.o \
- i2c.o \
- max7762x.o \
- max17050.o \
- mc.o \
- nx_emmc.o \
- sdmmc.o \
- sdmmc_driver.o \
- sdram.o \
- sdram_lp0.o \
- util.o \
- di.o \
gfx.o \
- pinmux.o \
- pkg1.o \
- pkg2.o \
- se.o \
- tsec.o \
- hw_init.o \
- smmu.o \
- max77620-rtc.o \
)
-OBJS += $(addprefix $(BUILD)/$(TARGET)/, \
+# Hardware.
+OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
+ clock.o cluster.o di.o gpio.o i2c.o mc.o sdram.o sdram_lp0.o pinmux.o se.o smmu.o tsec.o \
+ fuse.o \
+ sdmmc.o sdmmc_driver.o \
+ max17050.o max7762x.o max77620-rtc.o \
+ hw_init.o \
+)
+
+# Utilities.
+OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
+ btn.o util.o \
+)
+
+# Horizon.
+OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
+ nx_emmc.o \
+ pkg1.o pkg2.o sept.o \
+)
+
+# Libraries.
+OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
lz.o blz.o \
diskio.o ff.o ffunicode.o ffsystem.o \
)
+################################################################################
+
CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
CUSTOMDEFINES += -DLP_VER_MJ=$(LPVERSION_MAJOR) -DLP_VER_MN=$(LPVERSION_MINOR) -DLP_VER_BF=$(LPVERSION_BUGFX)
@@ -63,32 +64,34 @@ LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defs
MODULEDIRS := $(wildcard modules/*)
+################################################################################
+
.PHONY: all clean $(MODULEDIRS)
all: $(TARGET).bin
@echo -n "Payload size is "
- @wc -c < $(OUTPUT)/$(TARGET).bin
+ @wc -c < $(OUTPUTDIR)/$(TARGET).bin
@echo "Max size is 126296 Bytes."
clean:
@rm -rf $(OBJS)
- @rm -rf $(BUILD)
- @rm -rf $(OUTPUT)
+ @rm -rf $(BUILDDIR)
+ @rm -rf $(OUTPUTDIR)
$(MODULEDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)
-$(TARGET).bin: $(BUILD)/$(TARGET)/$(TARGET).elf $(MODULEDIRS)
- $(OBJCOPY) -S -O binary $< $(OUTPUT)/$@
+$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS)
+ $(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
-$(BUILD)/$(TARGET)/$(TARGET).elf: $(OBJS)
+$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
-$(BUILD)/$(TARGET)/%.o: %.c
+$(BUILDDIR)/$(TARGET)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
-$(BUILD)/$(TARGET)/%.o: %.S
- @mkdir -p "$(BUILD)"
- @mkdir -p "$(BUILD)/$(TARGET)"
- @mkdir -p "$(OUTPUT)"
+$(BUILDDIR)/$(TARGET)/%.o: %.S
+ @mkdir -p "$(BUILDDIR)"
+ @mkdir -p "$(BUILDDIR)/$(TARGET)"
+ @mkdir -p "$(OUTPUTDIR)"
$(CC) $(CFLAGS) -c $< -o $@
diff --git a/source/gfx/gfx.c b/source/gfx/gfx.c
index 90d97cf..fb0793c 100644
--- a/source/gfx/gfx.c
+++ b/source/gfx/gfx.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (C) 2018 CTCaer
+ * Copyright (C) 2018-2019 CTCaer
* Copyright (c) 2019 shchmue
*
* This program is free software; you can redistribute it and/or modify it
@@ -306,7 +306,7 @@ static void _gfx_putn(u32 v, int base, char fill, int fcnt)
gfx_puts(p);
}
-void gfx_put_small_sep(gfx_con_t *con)
+void gfx_put_small_sep()
{
u8 prevFontSize = gfx_con.fntsz;
gfx_con.fntsz = 8;
@@ -314,7 +314,7 @@ void gfx_put_small_sep(gfx_con_t *con)
gfx_con.fntsz = prevFontSize;
}
-void gfx_put_big_sep(gfx_con_t *con)
+void gfx_put_big_sep()
{
u8 prevFontSize = gfx_con.fntsz;
gfx_con.fntsz = 16;
diff --git a/source/gfx/gfx.h b/source/gfx/gfx.h
index 6e4137d..94cb0ed 100644
--- a/source/gfx/gfx.h
+++ b/source/gfx/gfx.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (C) 2018 CTCaer
+ * Copyright (C) 2018-2019 CTCaer
* Copyright (C) 2018 M4xw
*
* This program is free software; you can redistribute it and/or modify it
@@ -41,8 +41,8 @@ void gfx_hexdump(u32 base, const u8 *buf, u32 len);
void gfx_set_pixel(u32 x, u32 y, u32 color);
void gfx_line(int x0, int y0, int x1, int y1, u32 color);
-void gfx_put_small_sep(gfx_con_t *con);
-void gfx_put_big_sep(gfx_con_t *con);
+void gfx_put_small_sep();
+void gfx_put_big_sep();
void gfx_set_rect_grey(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
void gfx_set_rect_rgb(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
void gfx_set_rect_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
diff --git a/source/hos/pkg2.c b/source/hos/pkg2.c
index 395ffe2..4cece1c 100644
--- a/source/hos/pkg2.c
+++ b/source/hos/pkg2.c
@@ -41,11 +41,15 @@ static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2)
{
- u8 *ptr = pkg2->data;
- if (pkg2->sec_size[PKG2_SEC_INI1] == 0)
- ptr += *(u32 *)(ptr + 0x168);
+ u8 *ptr;
+ // Check for new pkg2 type.
+ if (!pkg2->sec_size[PKG2_SEC_INI1])
+ {
+ u32 kernel_ini1_off = *(u32 *)(pkg2->data + PKG2_NEWKERN_INI1_START);
+ ptr = pkg2->data + kernel_ini1_off;
+ }
else
- ptr += pkg2->sec_size[PKG2_SEC_KERNEL];
+ ptr = pkg2->data + pkg2->sec_size[PKG2_SEC_KERNEL];
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)ptr;
ptr += sizeof(pkg2_ini1_t);
diff --git a/source/hos/pkg2.h b/source/hos/pkg2.h
index 5fcece1..fe067ec 100644
--- a/source/hos/pkg2.h
+++ b/source/hos/pkg2.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
- * Copyright (C) 2018 CTCaer
+ * Copyright (C) 2018-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,
@@ -26,6 +26,8 @@
#define PKG2_SEC_KERNEL 0
#define PKG2_SEC_INI1 1
+#define PKG2_NEWKERN_INI1_START 0x168
+
typedef struct _pkg2_hdr_t
{
u8 ctr[0x10];
diff --git a/source/hos/sept.c b/source/hos/sept.c
index 2fdb9ad..129c585 100644
--- a/source/hos/sept.c
+++ b/source/hos/sept.c
@@ -90,7 +90,7 @@ int reboot_to_sept(const u8 *tsec_fw)
}
f_close(&fp);
- // Save auto boot config to payload, if any.
+ // Save auto boot config to sept payload, if any.
boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t));
memcpy(tmp_cfg, &b_cfg, sizeof(boot_cfg_t));
@@ -125,10 +125,8 @@ int reboot_to_sept(const u8 *tsec_fw)
(*sept)();
- return 1;
-
error:
- EPRINTF("Sept payloads not found in sd:/sept!\nPlace appropriate files and try again.");
+ EPRINTF("Sept files not found in sd:/sept!\nPlace appropriate files and try again.");
display_backlight_brightness(100, 1000);
btn_wait();
diff --git a/source/keys/keys.c b/source/keys/keys.c
index 8793d6b..31e1292 100644
--- a/source/keys/keys.c
+++ b/source/keys/keys.c
@@ -41,7 +41,6 @@
extern bool sd_mount();
extern void sd_unmount();
-extern void *sd_file_read(char *path);
extern int sd_save_to_file(void *buf, u32 size, const char *filename);
extern void power_off();
extern void reboot_normal();
@@ -228,7 +227,7 @@ static u32 _sprintf(char *buffer, const char *fmt, ...);
void dump_keys() {
display_backlight_brightness(100, 1000);
- gfx_clear_partial_grey(0x1B, 0, 1280);
+ gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
gfx_printf("[%kLo%kck%kpi%kck%k-R%kCM%k v%d.%d.%d%k]\n\n",
@@ -764,14 +763,14 @@ pkg2_done:
}
f_close(&fp);
- if (f_open(&fp, "emmc:/save/8000000000000043", FA_READ | FA_OPEN_EXISTING) || f_stat("emmc:/save/8000000000000043", &fno)) {
+ if (f_open(&fp, "emmc:/save/8000000000000043", FA_READ | FA_OPEN_EXISTING)) {
EPRINTF("Failed to open ns_appman save.");
goto dismount;
}
// locate sd seed
u8 read_buf[0x20] = {0};
- for (u32 i = 0; i < fno.fsize; i += 0x4000) {
+ for (u32 i = 0; i < f_size(&fp); i += 0x4000) {
if (f_lseek(&fp, i) || f_read(&fp, read_buf, 0x20, &read_bytes) || read_bytes != 0x20)
break;
if (!memcmp(temp_key, read_buf, 0x10)) {
diff --git a/source/main.c b/source/main.c
index e8d5132..3076551 100644
--- a/source/main.c
+++ b/source/main.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
*
- * Copyright (c) 2018 CTCaer
+ * Copyright (c) 2018-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,
@@ -74,32 +74,29 @@ void sd_unmount()
}
}
-void *sd_file_read(char *path)
+void *sd_file_read(const char *path, u32 *fsize)
{
- FIL fp;
- if (f_open(&fp, path, FA_READ) != FR_OK)
- return NULL;
+ FIL fp;
+ if (f_open(&fp, path, FA_READ) != FR_OK)
+ return NULL;
- u32 size = f_size(&fp);
- void *buf = malloc(size);
+ u32 size = f_size(&fp);
+ if (fsize)
+ *fsize = size;
- u8 *ptr = buf;
- while (size > 0)
- {
- u32 rsize = MIN(size, 512 * 512);
- if (f_read(&fp, ptr, rsize, NULL) != FR_OK)
- {
- free(buf);
- return NULL;
- }
+ void *buf = malloc(size);
- ptr += rsize;
- size -= rsize;
- }
+ if (f_read(&fp, buf, size, NULL) != FR_OK)
+ {
+ free(buf);
+ f_close(&fp);
- f_close(&fp);
+ return NULL;
+ }
- return buf;
+ f_close(&fp);
+
+ return buf;
}
int sd_save_to_file(void *buf, u32 size, const char *filename)
@@ -150,8 +147,8 @@ void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
extern void pivot_stack(u32 stack_top);
-void ipl_main() {
-
+void ipl_main()
+{
config_hw();
pivot_stack(IPL_STACK_TOP);
heap_init(IPL_HEAP_START);
diff --git a/source/power/bq24193.c b/source/power/bq24193.c
deleted file mode 100644
index 717c364..0000000
--- a/source/power/bq24193.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Battery charger driver for Nintendo Switch's TI BQ24193
- *
- * Copyright (C) 2018 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 .
- */
-
-#include "bq24193.h"
-#include "../soc/i2c.h"
-#include "../utils/util.h"
-
-int bq24193_get_property(enum BQ24193_reg_prop prop, int *value)
-{
- u8 data;
-
- switch (prop) {
- case BQ24193_InputVoltageLimit: // Input voltage limit (mV).
- data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_InputSource);
- data = (data & BQ24193_INCONFIG_VINDPM_MASK) >> 3;
- *value += ((data >> 0) & 1) ? 80 : 0;
- *value += ((data >> 1) & 1) ? 160 : 0;
- *value += ((data >> 2) & 1) ? 320 : 0;
- *value += ((data >> 3) & 1) ? 640 : 0;
- *value += 3880;
- break;
- case BQ24193_InputCurrentLimit: // Input current limit (mA).
- data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_InputSource);
- data &= BQ24193_INCONFIG_INLIMIT_MASK;
- switch (data)
- {
- case 0:
- *value = 100;
- break;
- case 1:
- *value = 150;
- break;
- case 2:
- *value = 500;
- break;
- case 3:
- *value = 900;
- break;
- case 4:
- *value = 1200;
- break;
- case 5:
- *value = 1500;
- break;
- case 6:
- *value = 2000;
- break;
- case 7:
- *value = 3000;
- break;
- }
- break;
- case BQ24193_SystemMinimumVoltage: // Minimum system voltage limit (mV).
- data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_PORConfig);
- *value = (data & BQ24193_PORCONFIG_SYSMIN_MASK) >> 1;
- *value *= 100;
- *value += 3000;
- break;
- case BQ24193_FastChargeCurrentLimit: // Fast charge current limit (mA).
- data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgCurr);
- data = (data & BQ24193_CHRGCURR_ICHG_MASK) >> 2;
- *value += ((data >> 0) & 1) ? 64 : 0;
- *value += ((data >> 1) & 1) ? 128 : 0;
- *value += ((data >> 2) & 1) ? 256 : 0;
- *value += ((data >> 3) & 1) ? 512 : 0;
- *value += ((data >> 4) & 1) ? 1024 : 0;
- *value += ((data >> 5) & 1) ? 2048 : 0;
- *value += 512;
- data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgCurr);
- data &= BQ24193_CHRGCURR_20PCT_MASK;
- if (data)
- *value = *value * 20 / 100; // Fast charge current limit is 20%.
- break;
- case BQ24193_ChargeVoltageLimit: // Charge voltage limit (mV).
- data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgVolt);
- data = (data & BQ24193_CHRGVOLT_VREG) >> 2;
- *value += ((data >> 0) & 1) ? 16 : 0;
- *value += ((data >> 1) & 1) ? 32 : 0;
- *value += ((data >> 2) & 1) ? 64 : 0;
- *value += ((data >> 3) & 1) ? 128 : 0;
- *value += ((data >> 4) & 1) ? 256 : 0;
- *value += ((data >> 5) & 1) ? 512 : 0;
- *value += 3504;
- break;
- case BQ24193_RechargeThreshold: // Recharge voltage threshold less than voltage limit (mV).
- data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgVolt);
- data &= BQ24193_IRTHERMAL_THERM_MASK;
- if (data)
- *value = 300;
- else
- *value = 100;
- break;
- case BQ24193_ThermalRegulation: // Thermal regulation threshold (oC).
- data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_IRCompThermal);
- data &= BQ24193_IRTHERMAL_THERM_MASK;
- switch (data)
- {
- case 0:
- *value = 60;
- break;
- case 1:
- *value = 80;
- break;
- case 2:
- *value = 100;
- break;
- case 3:
- *value = 120;
- break;
- }
- break;
- case BQ24193_ChargeStatus: // 0: Not charging, 1: Pre-charge, 2: Fast charging, 3: Charge termination done
- data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Status);
- *value = (data & BQ24193_STATUS_CHRG_MASK) >> 4;
- break;
- case BQ24193_TempStatus: // 0: Normal, 2: Warm, 3: Cool, 5: Cold, 6: Hot.
- data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_FaultReg);
- *value = data & BQ24193_FAULT_THERM_MASK;
- break;
- case BQ24193_DevID: // Dev ID.
- data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_VendorPart);
- *value = data & BQ24193_VENDORPART_DEV_MASK;
- break;
- case BQ24193_ProductNumber: // Product number.
- data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_VendorPart);
- *value = (data & BQ24193_VENDORPART_PN_MASK) >> 3;
- break;
- default:
- return -1;
- }
- return 0;
-}
-
-void bq24193_fake_battery_removal()
-{
- u8 value;
-
- // Disable watchdog to keep BATFET disabled.
- value = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgTermTimer);
- value &= ~BQ24193_CHRGTERM_WATCHDOG_MASK;
- i2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgTermTimer, value);
-
- // Force BATFET to disabled state. This disconnects the battery from the system.
- value = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Misc);
- value |= BQ24193_MISC_BATFET_DI_MASK;
- i2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Misc, value);
-}
diff --git a/source/power/bq24193.h b/source/power/bq24193.h
deleted file mode 100644
index 9c7b74e..0000000
--- a/source/power/bq24193.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Battery charger driver for Nintendo Switch's TI BQ24193
- *
- * Copyright (C) 2018 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 .
- */
-
-#ifndef __BQ24193_H_
-#define __BQ24193_H_
-
-#define BQ24193_I2C_ADDR 0x6B
-
-// REG 0 masks.
-#define BQ24193_INCONFIG_INLIMIT_MASK (7<<0)
-#define BQ24193_INCONFIG_VINDPM_MASK 0x78
-#define BQ24193_INCONFIG_HIZ_EN_MASK (1<<7)
-
-// REG 1 masks.
-#define BQ24193_PORCONFIG_BOOST_MASK (1<<0)
-#define BQ24193_PORCONFIG_SYSMIN_MASK (7<<1)
-#define BQ24193_PORCONFIG_CHGCONFIG_MASK (3<<4)
-#define BQ24193_PORCONFIG_I2CWATCHDOG_MASK (1<<6)
-#define BQ24193_PORCONFIG_RESET_MASK (1<<7)
-
-// REG 2 masks.
-#define BQ24193_CHRGCURR_20PCT_MASK (1<<0)
-#define BQ24193_CHRGCURR_ICHG_MASK 0xFC
-
-// REG 3 masks.
-#define BQ24193_PRECHRG_ITERM 0x0F
-#define BQ24193_PRECHRG_IPRECHG 0xF0
-
-// REG 4 masks.
-#define BQ24193_CHRGVOLT_VTHRES (1<<0)
-#define BQ24193_CHRGVOLT_BATTLOW (1<<1)
-#define BQ24193_CHRGVOLT_VREG 0xFC
-
-// REG 5 masks.
-#define BQ24193_CHRGTERM_ISET_MASK (1<<0)
-#define BQ24193_CHRGTERM_CHGTIMER_MASK (3<<1)
-#define BQ24193_CHRGTERM_ENTIMER_MASK (1<<3)
-#define BQ24193_CHRGTERM_WATCHDOG_MASK (3<<4)
-#define BQ24193_CHRGTERM_TERM_ST_MASK (1<<6)
-#define BQ24193_CHRGTERM_TERM_EN_MASK (1<<7)
-
-// REG 6 masks.
-#define BQ24193_IRTHERMAL_THERM_MASK (3<<0)
-#define BQ24193_IRTHERMAL_VCLAMP_MASK (7<<2)
-#define BQ24193_IRTHERMAL_BATTCOMP_MASK (7<<5)
-
-// REG 7 masks.
-#define BQ24193_MISC_INT_MASK (3<<0)
-#define BQ24193_MISC_VSET_MASK (1<<4)
-#define BQ24193_MISC_BATFET_DI_MASK (1<<5)
-#define BQ24193_MISC_TMR2X_EN_MASK (1<<6)
-#define BQ24193_MISC_DPDM_EN_MASK (1<<7)
-
-// REG 8 masks.
-#define BQ24193_STATUS_VSYS_MASK (1<<0)
-#define BQ24193_STATUS_THERM_MASK (1<<1)
-#define BQ24193_STATUS_PG_MASK (1<<2)
-#define BQ24193_STATUS_DPM_MASK (1<<3)
-#define BQ24193_STATUS_CHRG_MASK (3<<4)
-#define BQ24193_STATUS_VBUS_MASK (3<<6)
-
-// REG 9 masks.
-#define BQ24193_FAULT_THERM_MASK (7<<0)
-#define BQ24193_FAULT_BATT_OVP_MASK (1<<3)
-#define BQ24193_FAULT_CHARGE_MASK (3<<4)
-#define BQ24193_FAULT_BOOST_MASK (1<<6)
-#define BQ24193_FAULT_WATCHDOG_MASK (1<<7)
-
-// REG A masks.
-#define BQ24193_VENDORPART_DEV_MASK (3<<0)
-#define BQ24193_VENDORPART_PN_MASK (7<<3)
-
-enum BQ24193_reg {
- BQ24193_InputSource = 0x00,
- BQ24193_PORConfig = 0x01,
- BQ24193_ChrgCurr = 0x02,
- BQ24193_PreChrgTerm = 0x03,
- BQ24193_ChrgVolt = 0x04,
- BQ24193_ChrgTermTimer = 0x05,
- BQ24193_IRCompThermal = 0x06,
- BQ24193_Misc = 0x07,
- BQ24193_Status = 0x08,
- BQ24193_FaultReg = 0x09,
- BQ24193_VendorPart = 0x0A,
-};
-
-enum BQ24193_reg_prop {
- BQ24193_InputVoltageLimit, // REG 0.
- BQ24193_InputCurrentLimit, // REG 0.
- BQ24193_SystemMinimumVoltage, // REG 1.
- BQ24193_FastChargeCurrentLimit, // REG 2.
- BQ24193_ChargeVoltageLimit, // REG 4.
- BQ24193_RechargeThreshold, // REG 4.
- BQ24193_ThermalRegulation, // REG 6.
- BQ24193_ChargeStatus, // REG 8.
- BQ24193_TempStatus, // REG 9.
- BQ24193_DevID, // REG A.
- BQ24193_ProductNumber, // REG A.
-};
-
-int bq24193_get_property(enum BQ24193_reg_prop prop, int *value);
-void bq24193_fake_battery_removal();
-
-#endif /* __BQ24193_H_ */
diff --git a/source/sec/tsec.c b/source/sec/tsec.c
index c99d7a0..9f8d28e 100644
--- a/source/sec/tsec.c
+++ b/source/sec/tsec.c
@@ -28,7 +28,7 @@
#include "../mem/mc.h"
#include "../utils/util.h"
-/* #include "../gfx/gfx.h" */
+// #include "../gfx/gfx.h"
static int _tsec_dma_wait_idle()
{
@@ -187,7 +187,8 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
{
smmu_flush_all();
- if (k != se[SE_KEYTABLE_DATA0_REG_OFFSET / 4]) {
+ if (k != se[SE_KEYTABLE_DATA0_REG_OFFSET / 4])
+ {
k = se[SE_KEYTABLE_DATA0_REG_OFFSET / 4];
key[kidx++] = k;
}
diff --git a/source/soc/clock.c b/source/soc/clock.c
index 26808e2..f712935 100644
--- a/source/soc/clock.c
+++ b/source/soc/clock.c
@@ -364,10 +364,12 @@ static void _clock_sdmmc_clear_enable(u32 id)
static u32 _clock_sdmmc_table[8] = { 0 };
+#define PLLP_OUT0 0x0
+
static int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val)
{
u32 divisor = 0;
- u32 source = 0;
+ u32 source = PLLP_OUT0;
switch (val)
{
@@ -414,16 +416,16 @@ static int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val)
switch (id)
{
case SDMMC_1:
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = source | divisor;
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = (source << 29) | divisor;
break;
case SDMMC_2:
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = source | divisor;
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = (source << 29) | divisor;
break;
case SDMMC_3:
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = source | divisor;
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = (source << 29) | divisor;
break;
case SDMMC_4:
- CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = source | divisor;
+ CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = (source << 29) | divisor;
break;
}
diff --git a/source/soc/hw_init.c b/source/soc/hw_init.c
index 99f61eb..294505f 100644
--- a/source/soc/hw_init.c
+++ b/source/soc/hw_init.c
@@ -18,6 +18,13 @@
#include
#include "hw_init.h"
+#include "clock.h"
+#include "fuse.h"
+#include "gpio.h"
+#include "i2c.h"
+#include "pinmux.h"
+#include "pmc.h"
+#include "t210.h"
#include "../gfx/di.h"
#include "../mem/mc.h"
#include "../mem/sdram.h"
@@ -25,13 +32,6 @@
#include "../power/max7762x.h"
#include "../sec/se.h"
#include "../sec/se_t210.h"
-#include "../soc/clock.h"
-#include "../soc/fuse.h"
-#include "../soc/gpio.h"
-#include "../soc/i2c.h"
-#include "../soc/pinmux.h"
-#include "../soc/pmc.h"
-#include "../soc/t210.h"
#include "../storage/sdmmc.h"
#include "../utils/util.h"
diff --git a/source/storage/sdmmc.c b/source/storage/sdmmc.c
index 744cae9..585268b 100644
--- a/source/storage/sdmmc.c
+++ b/source/storage/sdmmc.c
@@ -19,13 +19,15 @@
#include "sdmmc.h"
#include "mmc.h"
#include "sd.h"
-#include "../utils/util.h"
+#include "../gfx/gfx.h"
#include "../mem/heap.h"
+#include "../utils/util.h"
-/*#include "gfx.h"
-#define DPRINTF(...) gfx_printf(__VA_ARGS__)*/
+//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
#define DPRINTF(...)
+extern boot_cfg_t b_cfg;
+
static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)
{
const u32 mask = (size < 32 ? 1 << size : 0) - 1;
@@ -425,7 +427,7 @@ static int _mmc_storage_enable_HS400(sdmmc_storage_t *storage)
static int _mmc_storage_enable_highspeed(sdmmc_storage_t *storage, u32 card_type, u32 type)
{
//TODO: this should be a config item.
- //---v
+ // --v
if (!1 || sdmmc_get_voltage(storage->sdmmc) != SDMMC_POWER_1_8)
goto out;
@@ -530,7 +532,9 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32
DPRINTF("[MMC] BKOPS enabled\n");
}
else
+ {
DPRINTF("[MMC] BKOPS disabled\n");
+ }
if (!_mmc_storage_enable_highspeed(storage, storage->ext_csd.card_type, type))
return 0;
@@ -704,7 +708,7 @@ int _sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf)
u32 tmp = 0;
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
- //Prepare buffer for unstuff_bits
+ //Prepare buffer for unstuff_bits
for (int i = 0; i < 8; i+=4)
{
storage->raw_scr[i + 3] = buf[i];
@@ -831,6 +835,7 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8
switch (type)
{
case 11:
+ // Fall through if not supported.
if (buf[13] & SD_MODE_UHS_SDR104)
{
type = 11;
@@ -839,7 +844,6 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8
storage->csd.busspeed = 104;
break;
}
- //Fall through.
case 10:
if (buf[13] & SD_MODE_UHS_SDR50)
{
@@ -876,7 +880,7 @@ int _sd_storage_enable_highspeed_high_volt(sdmmc_storage_t *storage, u8 *buf)
if (!_sd_storage_switch_get(storage, buf))
return 0;
//gfx_hexdump(0, (u8 *)buf, 64);
- if (!(buf[13] & 2))
+ if (!(buf[13] & SD_MODE_HIGH_SPEED))
return 1;
if (!_sd_storage_enable_highspeed(storage, 1, buf))
@@ -1011,6 +1015,11 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32
{
int is_version_1 = 0;
+ // Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
+ u32 sd_poweroff_time = (u32)get_tmr_ms() - b_cfg.sd_timeoff;
+ if (id == SDMMC_1 && (sd_poweroff_time < 100))
+ msleep(100 - sd_poweroff_time);
+
memset(storage, 0, sizeof(sdmmc_storage_t));
storage->sdmmc = sdmmc;
@@ -1103,7 +1112,9 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32
DPRINTF("[SD] switched to wide bus width\n");
}
else
+ {
DPRINTF("[SD] SD does not support wide bus width\n");
+ }
if (storage->is_low_voltage)
{
@@ -1129,7 +1140,9 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32
// Parse additional card info from sd status.
if (_sd_storage_get_ssr(storage, buf))
+ {
DPRINTF("[SD] got sd status\n");
+ }
free(buf);
return 1;
diff --git a/source/storage/sdmmc_driver.c b/source/storage/sdmmc_driver.c
index 2429228..23f6c0d 100644
--- a/source/storage/sdmmc_driver.c
+++ b/source/storage/sdmmc_driver.c
@@ -17,20 +17,22 @@
#include
-#include "sdmmc.h"
-#include "../utils/util.h"
-#include "../soc/clock.h"
#include "mmc.h"
+#include "sdmmc.h"
+#include "../gfx/gfx.h"
#include "../power/max7762x.h"
-#include "../soc/t210.h"
-#include "../soc/pmc.h"
-#include "../soc/pinmux.h"
+#include "../soc/clock.h"
#include "../soc/gpio.h"
+#include "../soc/pinmux.h"
+#include "../soc/pmc.h"
+#include "../soc/t210.h"
+#include "../utils/util.h"
-/*#include "gfx.h"
-#define DPRINTF(...) gfx_printf(__VA_ARGS__)*/
+//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
#define DPRINTF(...)
+extern boot_cfg_t b_cfg;
+
/*! SCMMC controller base addresses. */
static const u32 _sdmmc_bases[4] = {
0x700B0000,
@@ -116,7 +118,7 @@ static int _sdmmc_config_ven_ceata_clk(sdmmc_t *sdmmc, u32 id)
if (id == 4)
sdmmc->regs->venceatactl = (sdmmc->regs->venceatactl & 0xFFFFC0FF) | 0x2800;
- sdmmc->regs->field_1C0 &= 0xFFFDFFFF;
+ sdmmc->regs->ventunctl0 &= 0xFFFDFFFF;
if (id == 4)
{
if (!sdmmc->venclkctl_set)
@@ -168,11 +170,11 @@ static int _sdmmc_wait_type4(sdmmc_t *sdmmc)
sdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;
}
- sdmmc->regs->field_1B0 |= 0x80000000;
+ sdmmc->regs->vendllcal |= 0x80000000;
_sdmmc_get_clkcon(sdmmc);
u32 timeout = get_tmr_ms() + 5;
- while (sdmmc->regs->field_1B0 & 0x80000000)
+ while (sdmmc->regs->vendllcal & 0x80000000)
{
if (get_tmr_ms() > timeout)
{
@@ -182,7 +184,7 @@ static int _sdmmc_wait_type4(sdmmc_t *sdmmc)
}
timeout = get_tmr_ms() + 10;
- while (sdmmc->regs->field_1BC & 0x80000000)
+ while (sdmmc->regs->dllcfgstatus & 0x80000000)
{
if (get_tmr_ms() > timeout)
{
@@ -561,9 +563,9 @@ int sdmmc_config_tuning(sdmmc_t *sdmmc, u32 type, u32 cmd)
return 0;
}
- sdmmc->regs->field_1C0 = (sdmmc->regs->field_1C0 & 0xFFFF1FFF) | flag;
- sdmmc->regs->field_1C0 = (sdmmc->regs->field_1C0 & 0xFFFFE03F) | 0x40;
- sdmmc->regs->field_1C0 |= 0x20000;
+ sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag;
+ sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | 0x40;
+ sdmmc->regs->ventunctl0 |= 0x20000;
sdmmc->regs->hostctl2 |= SDHCI_CTRL_EXEC_TUNING;
for (u32 i = 0; i < max; i++)
@@ -1000,8 +1002,8 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int n
sdmmc->clock_stopped = 0;
//TODO: make this skip-able.
- sdmmc->regs->field_1F0 |= 0x80000;
- sdmmc->regs->field_1AC &= 0xFFFFFFFB;
+ sdmmc->regs->iospare |= 0x80000;
+ sdmmc->regs->veniotrimctl &= 0xFFFFFFFB;
static const u32 trim_values[] = { 2, 8, 3, 8 };
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xE0FFFFFF) | (trim_values[sdmmc->id] << 24);
sdmmc->regs->sdmemcmppadctl = (sdmmc->regs->sdmemcmppadctl & 0xF) | 7;
@@ -1036,7 +1038,9 @@ void sdmmc_end(sdmmc_t *sdmmc)
if (sdmmc->id == SDMMC_1)
{
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
- msleep(1); // To power cycle min 1ms without power is needed.
+ max77620_regulator_enable(REGULATOR_LDO2, 0);
+ b_cfg.sd_timeoff = get_tmr_ms(); // Some sandisc U1 cards need 100ms for a power cycle.
+ msleep(1); // To power cycle, min 1ms without power is needed.
}
_sdmmc_get_clkcon(sdmmc);
diff --git a/source/storage/sdmmc_t210.h b/source/storage/sdmmc_t210.h
index 66ff9f1..e11c3ff 100644
--- a/source/storage/sdmmc_t210.h
+++ b/source/storage/sdmmc_t210.h
@@ -115,18 +115,18 @@ typedef struct _t210_sdmmc_t
vu32 vendebouncecnt;
vu32 venmiscctl;
vu32 res6[34];
- vu32 field_1AC;
- vu32 field_1B0;
+ vu32 veniotrimctl;
+ vu32 vendllcal;
vu8 res7[8];
- vu32 field_1BC;
- vu32 field_1C0;
+ vu32 dllcfgstatus;
+ vu32 ventunctl0;
vu32 field_1C4;
vu8 field_1C8[24];
vu32 sdmemcmppadctl;
vu32 autocalcfg;
vu32 autocalintval;
vu32 autocalsts;
- vu32 field_1F0;
+ vu32 iospare;
} t210_sdmmc_t;
#endif
diff --git a/source/utils/types.h b/source/utils/types.h
index 3c22692..5f9ccf3 100644
--- a/source/utils/types.h
+++ b/source/utils/types.h
@@ -80,7 +80,8 @@ typedef struct __attribute__((__packed__)) _boot_cfg_t
u8 autoboot;
u8 autoboot_list;
u8 extra_cfg;
- u8 rsvd[128];
+ u32 sd_timeoff;
+ u8 rsvd[124];
} boot_cfg_t;
typedef struct __attribute__((__packed__)) _reloc_meta_t
diff --git a/source/utils/util.c b/source/utils/util.c
index c34764a..6474d5a 100644
--- a/source/utils/util.c
+++ b/source/utils/util.c
@@ -106,45 +106,3 @@ void power_off()
//TODO: we should probably make sure all regulators are powered off properly.
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF);
}
-
-#define CRC32C_POLY 0x82F63B78
-u32 crc32c(const void *buf, u32 len)
-{
- const u8 *cbuf = (const u8 *)buf;
- u32 crc = 0xFFFFFFFF;
- while (len--)
- {
- crc ^= *cbuf++;
- for (int i = 0; i < 8; i++)
- crc = crc & 1 ? (crc >> 1) ^ CRC32C_POLY : crc >> 1;
- }
- return ~crc;
-}
-
-u32 memcmp32sparse(const u32 *buf1, const u32 *buf2, u32 len)
-{
- u32 len32 = len / 4;
-
- if (!(len32 % 32))
- {
- while (len32)
- {
- len32 -= 32;
- if(buf1[len32] != buf2[len32])
- return 1;
- }
- }
- else
- {
- while (len32)
- {
- len32 -= 32;
- if(buf1[len32] != buf2[len32])
- return 1;
- if (len32 < 32)
- return 0;
- }
- }
-
- return 0;
-}
diff --git a/source/utils/util.h b/source/utils/util.h
index 3b57703..f261035 100644
--- a/source/utils/util.h
+++ b/source/utils/util.h
@@ -39,10 +39,5 @@ void reboot_normal();
void reboot_rcm();
void power_off();
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
-u32 crc32c(const void *buf, u32 len);
-
-/* This is a faster implementation of memcmp that checks two u32 values */
-/* every 128 Bytes block. Intented only for Backup and Restore */
-u32 memcmp32sparse(const u32 *buf1, const u32 *buf2, u32 len);
#endif