diff --git a/Makefile b/Makefile index 164f7205..0d8c0d9a 100644 --- a/Makefile +++ b/Makefile @@ -91,8 +91,10 @@ OBJECTS := \ chickens.o \ chickens_avalanche.o \ chickens_blizzard.o \ + chickens_everest.o \ chickens_firestorm.o \ chickens_icestorm.o \ + chickens_sawtooth.o \ clk.o \ cpufreq.o \ dapf.o \ diff --git a/src/chickens.c b/src/chickens.c index af9c7bc0..97572462 100644 --- a/src/chickens.c +++ b/src/chickens.c @@ -22,6 +22,8 @@ #define MIDR_PART_T6020_AVALANCHE 0x35 #define MIDR_PART_T6021_BLIZZARD 0x38 #define MIDR_PART_T6021_AVALANCHE 0x39 +#define MIDR_PART_T6031_EVEREST 0x49 +#define MIDR_PART_T6031_SAWTOOTH 0x48 #define MIDR_REV_LOW GENMASK(3, 0) #define MIDR_PART GENMASK(15, 4) @@ -37,6 +39,8 @@ void init_t6020_blizzard(void); void init_t6020_avalanche(int rev); void init_t6021_blizzard(void); void init_t6021_avalanche(int rev); +void init_t6031_sawtooth(void); +void init_t6031_everest(int rev); const char *init_cpu(void) { @@ -123,6 +127,16 @@ const char *init_cpu(void) init_t6021_blizzard(); break; + case MIDR_PART_T6031_EVEREST: + cpu = "M3 Max Everest"; + init_t6031_everest(rev); + break; + + case MIDR_PART_T6031_SAWTOOTH: + cpu = "M3 Max Sawtooth"; + init_t6031_sawtooth(); + break; + default: uart_puts(" Unknown CPU type"); break; diff --git a/src/chickens_avalanche.c b/src/chickens_avalanche.c index 1ecccef2..f75611d1 100644 --- a/src/chickens_avalanche.c +++ b/src/chickens_avalanche.c @@ -40,7 +40,8 @@ void init_t8112_avalanche(int rev) reg_mask(SYS_IMP_APL_HID3, HID3_DEV_PCIE_THROTTLE_LIMIT_MASK, HID3_DEV_PCIE_THROTTLE_LIMIT(60)); reg_set(SYS_IMP_APL_HID3, HID3_DEV_PCIE_THROTTLE_ENABLE); - reg_set(SYS_IMP_APL_HID18, HID18_AVL_UNK27 | HID18_AVL_UNK29); + reg_set(SYS_IMP_APL_HID18, + HID18_GEXIT_EL_SPECULATION_DISABLE | HID18_GENTER_SPECULATION_DISABLE); reg_set(SYS_IMP_APL_HID16, HID16_AVL_UNK12); if (rev == 0) { @@ -59,7 +60,8 @@ void init_t6020_avalanche(int rev) reg_mask(SYS_IMP_APL_HID3, HID3_DEV_PCIE_THROTTLE_LIMIT_MASK, HID3_DEV_PCIE_THROTTLE_LIMIT(62)); reg_set(SYS_IMP_APL_HID3, HID3_DEV_PCIE_THROTTLE_ENABLE); - reg_set(SYS_IMP_APL_HID18, HID18_AVL_UNK27 | HID18_AVL_UNK29); + reg_set(SYS_IMP_APL_HID18, + HID18_GEXIT_EL_SPECULATION_DISABLE | HID18_GENTER_SPECULATION_DISABLE); reg_set(SYS_IMP_APL_HID16, HID16_AVL_UNK12); reg_mask(SYS_IMP_APL_HID5, HID5_BLZ_UNK_19_18_MASK, HID5_BLZ_UNK18); @@ -73,7 +75,8 @@ void init_t6021_avalanche(int rev) reg_mask(SYS_IMP_APL_HID3, HID3_DEV_PCIE_THROTTLE_LIMIT_MASK, HID3_DEV_PCIE_THROTTLE_LIMIT(62)); reg_set(SYS_IMP_APL_HID3, HID3_DEV_PCIE_THROTTLE_ENABLE); - reg_set(SYS_IMP_APL_HID18, HID18_AVL_UNK27 | HID18_AVL_UNK29); + reg_set(SYS_IMP_APL_HID18, + HID18_GEXIT_EL_SPECULATION_DISABLE | HID18_GENTER_SPECULATION_DISABLE); reg_set(SYS_IMP_APL_HID16, HID16_AVL_UNK12); reg_mask(SYS_IMP_APL_HID5, HID5_BLZ_UNK_19_18_MASK, HID5_BLZ_UNK19); diff --git a/src/chickens_everest.c b/src/chickens_everest.c new file mode 100644 index 00000000..2f9ac25c --- /dev/null +++ b/src/chickens_everest.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: MIT */ + +#include "cpu_regs.h" +#include "uart.h" +#include "utils.h" +static void init_common_everest(void) +{ + reg_set(SYS_IMP_APL_HID12, BIT(46)); + reg_set(SYS_IMP_APL_HID3, BIT(63)); + reg_mask(SYS_IMP_APL_HID3, GENMASK(ULONG(62), ULONG(56)), BIT(60) | BIT(59) | BIT(58)); + reg_clr(SYS_IMP_APL_HID3, BIT(4)); + reg_set(SYS_IMP_APL_HID9, BIT(17)); + reg_mask(SYS_IMP_APL_HID13, + HID13_POST_OFF_CYCLES_MASK | HID13_POST_ON_CYCLES_MASK | HID13_PRE_CYCLES_MASK | + HID13_GROUP0_FF1_DELAY_MASK | HID13_GROUP0_FF2_DELAY_MASK | + HID13_GROUP0_FF3_DELAY_MASK | HID13_GROUP0_FF4_DELAY_MASK | + HID13_GROUP0_FF5_DELAY_MASK | HID13_GROUP0_FF6_DELAY_MASK | + HID13_GROUP0_FF7_DELAY_MASK | HID13_RESET_CYCLES_MASK, + HID13_POST_OFF_CYCLES(4) | HID13_POST_ON_CYCLES(5) | HID13_PRE_CYCLES(1) | + HID13_GROUP0_FF1_DELAY(4) | HID13_GROUP0_FF2_DELAY(4) | HID13_GROUP0_FF3_DELAY(4) | + HID13_GROUP0_FF4_DELAY(4) | HID13_GROUP0_FF5_DELAY(4) | HID13_GROUP0_FF6_DELAY(4) | + HID13_GROUP0_FF7_DELAY(4) | HID13_RESET_CYCLES(0)); + reg_set(SYS_IMP_APL_HID16, BIT(54)); + reg_set(SYS_IMP_APL_HID18, + HID18_GEXIT_EL_SPECULATION_DISABLE | HID18_GENTER_SPECULATION_DISABLE); + + msr(SYS_IMP_APL_HID26, HID26_GROUP1_OFFSET(0xF88F65588LL) | HID26_GROUP2_OFFSET(0x3F28)); + reg_mask(SYS_IMP_APL_HID27, + GENMASK(43, 40) | GENMASK(39, 36) | GENMASK(35, 32) | GENMASK(31, 28) | + GENMASK(27, 24) | GENMASK(23, 20) | GENMASK(19, 16) | GENMASK(15, 8) | + GENMASK(7, 4) | GENMASK(3, 0), + BIT(40) | BIT(36) | BIT(32) | BIT(28) | BIT(24) | BIT(20) | BIT(16) | 0x2b00uL | + BIT(4) | BIT(0)); + /* This is new to M3 and i have no idea what it is yet */ + reg_set(s3_0_c15_c2_3, BIT(3)); + reg_clr(s3_0_c15_c2_4, BIT(0) | BIT(1) | BIT(16) | BIT(17) | BIT(18) | BIT(22)); +} + +void init_t6031_everest(int rev) +{ + UNUSED(rev); + msr(s3_1_c15_c1_5, 0x3uL); + msr(s3_4_c15_c14_6, 0x3uL); + init_common_everest(); + reg_set(SYS_IMP_APL_HID4, HID4_ENABLE_LFSR_STALL_LOAD_PIPE2_ISSUE); +} \ No newline at end of file diff --git a/src/chickens_firestorm.c b/src/chickens_firestorm.c index 696761bf..a4cd96d2 100644 --- a/src/chickens_firestorm.c +++ b/src/chickens_firestorm.c @@ -72,7 +72,7 @@ void init_t8103_firestorm(int rev) reg_set(SYS_IMP_APL_HID1, HID1_ENABLE_MDSB_STALL_PIPELINE_ECO | HID1_ENABLE_BR_KILL_LIMIT); if (rev >= 0x11) - reg_set(SYS_IMP_APL_HID18, HID18_SPAREBIT17); + reg_set(SYS_IMP_APL_HID18, HID18_PREF_REPLAY_DISABLE); } void init_t6000_firestorm(int rev) @@ -88,7 +88,7 @@ void init_t6000_firestorm(int rev) reg_set(SYS_IMP_APL_HID4, HID4_ENABLE_LFSR_STALL_LOAD_PIPE2_ISSUE | HID4_ENABLE_LFSR_STALL_STQ_REPLAY); - reg_set(SYS_IMP_APL_HID18, HID18_SPAREBIT17); + reg_set(SYS_IMP_APL_HID18, HID18_PREF_REPLAY_DISABLE); } } @@ -108,6 +108,6 @@ void init_t6001_firestorm(int rev) if (rev >= 0x10) { reg_set(SYS_IMP_APL_HID1, HID1_ENABLE_BR_KILL_LIMIT); - reg_set(SYS_IMP_APL_HID18, HID18_SPAREBIT17); + reg_set(SYS_IMP_APL_HID18, HID18_PREF_REPLAY_DISABLE); } } diff --git a/src/chickens_sawtooth.c b/src/chickens_sawtooth.c new file mode 100644 index 00000000..8e9fe317 --- /dev/null +++ b/src/chickens_sawtooth.c @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: MIT */ + +#include "cpu_regs.h" +#include "utils.h" + +static void init_common_sawtooth(void) +{ + reg_set(SYS_IMP_APL_EHID0, EHID0_BLI_UNK32); +} + +void init_t6031_sawtooth(void) +{ + init_common_sawtooth(); + + reg_mask(SYS_IMP_APL_EHID9, EHID9_DEV_2_THROTTLE_LIMIT_MASK, EHID9_DEV_2_THROTTLE_LIMIT(62)); + reg_set(SYS_IMP_APL_EHID9, EHID9_DEV_2_THROTTLE_ENABLE); + reg_set(SYS_IMP_APL_EHID18, EHID18_BLZ_UNK34); + + reg_mask(SYS_IMP_APL_HID5, HID5_BLZ_UNK_19_18_MASK, HID5_BLZ_UNK19); +} diff --git a/src/cpu_regs.h b/src/cpu_regs.h index de74d7e4..744f092a 100644 --- a/src/cpu_regs.h +++ b/src/cpu_regs.h @@ -299,6 +299,8 @@ #define HID11_ENABLE_FIX_UC_55719865 BIT(15) #define HID11_DISABLE_LD_NT_WIDGET BIT(59) +#define SYS_IMP_APL_HID12 sys_reg(3, 0, 15, 12, 0) + #define SYS_IMP_APL_HID13 sys_reg(3, 0, 15, 14, 0) #define HID13_POST_OFF_CYCLES(x) ((ULONG(x))) #define HID13_POST_OFF_CYCLES_MASK GENMASK(6, 0) @@ -333,12 +335,12 @@ #define HID16_ENABLE_MPX_PICK_45 BIT(61) #define HID16_ENABLE_MP_CYCLONE_7 BIT(62) -#define SYS_IMP_APL_HID18 sys_reg(3, 0, 15, 11, 2) -#define HID18_HVC_SPECULATION_DISABLE BIT(14) -#define HID18_AVL_UNK27 BIT(27) -#define HID18_AVL_UNK29 BIT(29) -#define HID18_SPAREBIT7 BIT(39) -#define HID18_SPAREBIT17 BIT(49) +#define SYS_IMP_APL_HID18 sys_reg(3, 0, 15, 11, 2) +#define HID18_HVC_SPECULATION_DISABLE BIT(14) +#define HID18_GEXIT_EL_SPECULATION_DISABLE BIT(27) +#define HID18_GENTER_SPECULATION_DISABLE BIT(29) +#define HID18_BTP_BRN_DISABLE BIT(39) +#define HID18_PREF_REPLAY_DISABLE BIT(49) #define SYS_IMP_APL_EHID18 sys_reg(3, 0, 15, 11, 3) #define EHID18_BLZ_UNK34 BIT(34) @@ -401,11 +403,12 @@ #define EHID20_FORCE_NONSPEC_TARGETED_TIMER_SEL(x) ((ULONG(x)) << 21) #define EHID20_FORCE_NONSPEC_TARGETED_TIMER_SEL_MASK (3UL << 21) -#define SYS_IMP_APL_HID21 sys_reg(3, 0, 15, 1, 3) +#define SYS_IMP_APL_HID21 sys_reg(3, 0, 15, 1, 3) +// In 6031's, this is marked as "wfi_full_quis" #define HID21_ENABLE_LDREX_FILL_REPLY BIT(19) -#define HID21_LDQ_RTR_WAIT_FOR_OLD_ST_REL_COMPLETION BIT(33) -#define HID21_DISABLE_CDP_REPLY_PURGED_TRANSACTION BIT(34) -#define HID21_AVL_UNK52 BIT(52) +#define HID21_LDQ_RTR_WAIT_FOR_OLD_ST_REL_COMPLETION BIT(34) +#define HID21_DISABLE_CDP_REPLY_PURGED_TRANSACTION BIT(35) +#define HID21_PURGE_MMU_ON_ANY_SPR_SYNC BIT(52) #define SYS_IMP_APL_HID26 sys_reg(3, 0, 15, 0, 3) #define HID26_GROUP1_OFFSET(x) ((ULONG(x)) << 0) @@ -617,3 +620,7 @@ #define IPI_SR_PENDING BIT(0) #define SYS_IMP_APL_IPI_CR_EL1 sys_reg(3, 5, 15, 3, 1) + +/* Lockdown registers */ +#define SYS_IMP_APL_SPR_LOCKDOWN_EL2 sys_reg(3, 4, 15, 0, 5) +#define SYS_IMP_APL_SPR_LOCKDOWN_EL1 sys_reg(3, 4, 15, 0, 6) diff --git a/src/main.c b/src/main.c index 6bf7b301..66c05ba9 100644 --- a/src/main.c +++ b/src/main.c @@ -113,7 +113,6 @@ void run_actions(void) printf("Valid payload found\n"); return; } - fb_set_active(true); printf("No valid payload found\n"); diff --git a/src/mcc.c b/src/mcc.c index 1ba82c79..37538839 100644 --- a/src/mcc.c +++ b/src/mcc.c @@ -23,6 +23,12 @@ static bool mcc_initialized = false; #define T6000_DCS_STRIDE 0x100000 #define T6000_DCS_COUNT 4 +#define T6031_PLANE_OFFSET 0 +#define T6031_PLANE_STRIDE 0x40000 +#define T6031_GLOBAL_OFFSET 0x100000 +#define T6031_DCS_OFFSET 0x400000 +#define T6031_DCS_STRIDE 0x200000 + #define PLANE_TZ_MAX_REGS 4 struct tz_regs { @@ -49,6 +55,14 @@ struct tz_regs t602x_tz_regs = { .enable = 0x6c8, }; +struct tz_regs t603x_tz_regs = { + .count = 4, + .stride = 0x14, + .start = 0x6d8, + .end = 0x6dc, + .enable = 0x6e4, +}; + #define PLANE_CACHE_ENABLE 0x1c00 #define PLANE_CACHE_STATUS 0x1c04 @@ -64,6 +78,12 @@ struct tz_regs t602x_tz_regs = { (FIELD_PREP(T6000_CACHE_STATUS_DATA_COUNT, T6000_CACHE_WAYS) | \ FIELD_PREP(T6000_CACHE_STATUS_TAG_COUNT, T6000_CACHE_WAYS)) +#define T6031_CACHE_WAYS 12 +#define T6031_CACHE_STATUS_MASK (T6000_CACHE_STATUS_DATA_COUNT | T6000_CACHE_STATUS_TAG_COUNT) +#define T6031_CACHE_STATUS_VAL \ + (FIELD_PREP(T6000_CACHE_STATUS_DATA_COUNT, T6031_CACHE_WAYS) | \ + FIELD_PREP(T6000_CACHE_STATUS_TAG_COUNT, T6031_CACHE_WAYS)) + #define T8103_CACHE_WAYS 16 #define T8103_CACHE_STATUS_MASK (T8103_CACHE_STATUS_DATA_COUNT | T8103_CACHE_STATUS_TAG_COUNT) #define T8103_CACHE_STATUS_VAL \ @@ -134,6 +154,8 @@ int mcc_enable_cache(void) if (!mcc_initialized) return -1; + /* The 6030 memory controller supports setting a waymask, but the desktop chips do not appear to + use it */ for (int mcc = 0; mcc < mcc_count; mcc++) { for (int plane = 0; plane < mcc_regs[mcc].plane_count; plane++) { plane_write32(mcc, plane, PLANE_CACHE_ENABLE, mcc_regs[mcc].cache_enable_val); @@ -161,7 +183,12 @@ int mcc_unmap_carveouts(void) mcc_carveout_count = 0; memset(mcc_carveouts, 0, sizeof mcc_carveouts); + // All MCCs and planes should have identical configs + // Note: For unhandled machines, the TZ regions can be found (on m1, m2, m3) by looking at + // region-id-2 and region-id-4 on a booted macos, in the /chosen/carveout-memory-map DT node. + // This can be used along with dumping the mcc reg space to find the correct start/end/enable + // above. for (u32 i = 0; i < mcc_regs[0].tz->count; i++) { uint64_t off = mcc_regs[0].tz->stride * i; uint64_t start = plane_read32(0, 0, mcc_regs[0].tz->start + off); @@ -291,6 +318,72 @@ int mcc_init_t6000(int node, int *path, bool t602x) return 0; } +int mcc_init_t6031(int node, int *path) +{ + u32 reg_len; + u32 reg_offset = 3; + + if (!adt_getprop(adt, node, "reg", ®_len)) { + printf("MCC: Failed to get reg property!\n"); + return -1; + } + + mcc_count = reg_len / 16 - reg_offset; + + printf("MCC: Initializing T6031 MCCs (%d instances)...\n", mcc_count); + + if (mcc_count > MAX_MCC_INSTANCES) { + printf("MCC: Too many instances, increase MAX_MCC_INSTANCES!\n"); + mcc_count = MAX_MCC_INSTANCES; + } + + u32 plane_count = 0; + u32 dcs_count = 0; + + if (!ADT_GETPROP(adt, node, "dcs-count-per-amcc", &dcs_count)) { + printf("MCC: Failed to get dcs count!\n"); + return -1; + } + + if (!ADT_GETPROP(adt, node, "plane-count-per-amcc", &plane_count)) { + printf("MCC: Failed to get plane count!\n"); + return -1; + } + + for (int i = 0; i < mcc_count; i++) { + u64 base; + if (adt_get_reg(adt, path, "reg", i + reg_offset, &base, NULL)) { + printf("MCC: Failed to get reg index %d!\n", i + reg_offset); + return -1; + } + + mcc_regs[i].plane_base = base + T6031_PLANE_OFFSET; + mcc_regs[i].plane_stride = T6031_PLANE_STRIDE; + mcc_regs[i].plane_count = plane_count; + + mcc_regs[i].global_base = base + T6031_GLOBAL_OFFSET; + + mcc_regs[i].dcs_base = base + T6031_DCS_OFFSET; + mcc_regs[i].dcs_stride = T6031_DCS_STRIDE; + mcc_regs[i].dcs_count = dcs_count; + + mcc_regs[i].cache_enable_val = 1; + mcc_regs[i].cache_ways = T6031_CACHE_WAYS; + mcc_regs[i].cache_status_mask = T6031_CACHE_STATUS_MASK; + mcc_regs[i].cache_status_val = T6031_CACHE_STATUS_VAL; + mcc_regs[i].cache_disable = 0; + + mcc_regs[i].tz = &t603x_tz_regs; + } + + printf("MCC: Initialized T6031 MCCs (%d instances, %d planes, %d channels)\n", mcc_count, + mcc_regs[0].plane_count, mcc_regs[0].dcs_count); + + mcc_initialized = true; + + return 0; +} + int mcc_init(void) { int path[8]; @@ -309,8 +402,10 @@ int mcc_init(void) return mcc_init_t6000(node, path, false); } else if (adt_is_compatible(adt, node, "mcc,t6020")) { return mcc_init_t6000(node, path, true); + } else if (adt_is_compatible(adt, node, "mcc,t6031")) { + return mcc_init_t6031(node, path); } else { - printf("MCC: Unsupported version\n"); + printf("MCC: Unsupported version:%s\n", adt_get_property(adt, node, "compatible")->value); return -1; } } diff --git a/src/soc.h b/src/soc.h index 7bd33a2c..eb375eda 100644 --- a/src/soc.h +++ b/src/soc.h @@ -26,6 +26,8 @@ #define EARLY_UART_BASE 0x39b200000 #elif TARGET == T8112 #define EARLY_UART_BASE 0x235200000 +#elif TARGET == T6034 || TARGET == T6031 +#define EARLY_UART_BASE 0x391200000 #endif #endif diff --git a/tools/apple_regs.json b/tools/apple_regs.json index 7cebf57a..9b8cb739 100644 --- a/tools/apple_regs.json +++ b/tools/apple_regs.json @@ -29,6 +29,8 @@ {"index": 0, "name": "EHID18_EL1", "fullname": "Hardware Implementation-Dependent Register 18 (E-core)", "enc": [3, 0, 15, 11, 3 ], "width": 64}, {"index": 0, "name": "EHID20_EL1", "fullname": "Hardware Implementation-Dependent Register 20 (E-core)", "enc": [3, 0, 15, 1, 2 ], "width": 64}, {"index": 0, "name": "HID21_EL1", "fullname": "Hardware Implementation-Dependent Register 21", "enc": [3, 0, 15, 1, 3 ], "width": 64}, + {"index": 0, "name": "HID26_EL1", "fullname": "Hardware Implementation-Dependent Register 26", "enc": [3, 0, 15, 0, 3 ], "width": 64}, + {"index": 0, "name": "HID27_EL1", "fullname": "Hardware Implementation-Dependent Register 27", "enc": [3, 0, 15, 0, 4 ], "width": 64}, {"index": 0, "name": "PMCR0_EL1", "fullname": "Performance Monitor Control Register 0", "enc": [3, 1, 15, 0, 0 ], "width": 64, "fieldsets": [{"fields": [ {"name": "PMC0_EN", "msb": 0, "lsb": 0},