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