Skip to content

Commit c45da55

Browse files
dberlinmarcan
authored andcommitted
More support for M3 chips
The UART base has moved from the M2 chips. Everest settings introduce some changes to unknown registers The MCC data has changed as well. There is a drive-by change where I discovered what some of the unknown HID18 bits are and documented them. Signed-off-by: Daniel Berlin <[email protected]>
1 parent 9f846b1 commit c45da55

11 files changed

Lines changed: 208 additions & 18 deletions

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,10 @@ OBJECTS := \
9191
chickens.o \
9292
chickens_avalanche.o \
9393
chickens_blizzard.o \
94+
chickens_everest.o \
9495
chickens_firestorm.o \
9596
chickens_icestorm.o \
97+
chickens_sawtooth.o \
9698
clk.o \
9799
cpufreq.o \
98100
dapf.o \

src/chickens.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#define MIDR_PART_T6020_AVALANCHE 0x35
2323
#define MIDR_PART_T6021_BLIZZARD 0x38
2424
#define MIDR_PART_T6021_AVALANCHE 0x39
25+
#define MIDR_PART_T6031_EVEREST 0x49
26+
#define MIDR_PART_T6031_SAWTOOTH 0x48
2527

2628
#define MIDR_REV_LOW GENMASK(3, 0)
2729
#define MIDR_PART GENMASK(15, 4)
@@ -37,6 +39,8 @@ void init_t6020_blizzard(void);
3739
void init_t6020_avalanche(int rev);
3840
void init_t6021_blizzard(void);
3941
void init_t6021_avalanche(int rev);
42+
void init_t6031_sawtooth(void);
43+
void init_t6031_everest(int rev);
4044

4145
const char *init_cpu(void)
4246
{
@@ -123,6 +127,16 @@ const char *init_cpu(void)
123127
init_t6021_blizzard();
124128
break;
125129

130+
case MIDR_PART_T6031_EVEREST:
131+
cpu = "M3 Max Everest";
132+
init_t6031_everest(rev);
133+
break;
134+
135+
case MIDR_PART_T6031_SAWTOOTH:
136+
cpu = "M3 Max Sawtooth";
137+
init_t6031_sawtooth();
138+
break;
139+
126140
default:
127141
uart_puts(" Unknown CPU type");
128142
break;

src/chickens_avalanche.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ void init_t8112_avalanche(int rev)
4040

4141
reg_mask(SYS_IMP_APL_HID3, HID3_DEV_PCIE_THROTTLE_LIMIT_MASK, HID3_DEV_PCIE_THROTTLE_LIMIT(60));
4242
reg_set(SYS_IMP_APL_HID3, HID3_DEV_PCIE_THROTTLE_ENABLE);
43-
reg_set(SYS_IMP_APL_HID18, HID18_AVL_UNK27 | HID18_AVL_UNK29);
43+
reg_set(SYS_IMP_APL_HID18,
44+
HID18_GEXIT_EL_SPECULATION_DISABLE | HID18_GENTER_SPECULATION_DISABLE);
4445
reg_set(SYS_IMP_APL_HID16, HID16_AVL_UNK12);
4546

4647
if (rev == 0) {
@@ -59,7 +60,8 @@ void init_t6020_avalanche(int rev)
5960

6061
reg_mask(SYS_IMP_APL_HID3, HID3_DEV_PCIE_THROTTLE_LIMIT_MASK, HID3_DEV_PCIE_THROTTLE_LIMIT(62));
6162
reg_set(SYS_IMP_APL_HID3, HID3_DEV_PCIE_THROTTLE_ENABLE);
62-
reg_set(SYS_IMP_APL_HID18, HID18_AVL_UNK27 | HID18_AVL_UNK29);
63+
reg_set(SYS_IMP_APL_HID18,
64+
HID18_GEXIT_EL_SPECULATION_DISABLE | HID18_GENTER_SPECULATION_DISABLE);
6365
reg_set(SYS_IMP_APL_HID16, HID16_AVL_UNK12);
6466

6567
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)
7375

7476
reg_mask(SYS_IMP_APL_HID3, HID3_DEV_PCIE_THROTTLE_LIMIT_MASK, HID3_DEV_PCIE_THROTTLE_LIMIT(62));
7577
reg_set(SYS_IMP_APL_HID3, HID3_DEV_PCIE_THROTTLE_ENABLE);
76-
reg_set(SYS_IMP_APL_HID18, HID18_AVL_UNK27 | HID18_AVL_UNK29);
78+
reg_set(SYS_IMP_APL_HID18,
79+
HID18_GEXIT_EL_SPECULATION_DISABLE | HID18_GENTER_SPECULATION_DISABLE);
7780
reg_set(SYS_IMP_APL_HID16, HID16_AVL_UNK12);
7881

7982
reg_mask(SYS_IMP_APL_HID5, HID5_BLZ_UNK_19_18_MASK, HID5_BLZ_UNK19);

src/chickens_everest.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* SPDX-License-Identifier: MIT */
2+
3+
#include "cpu_regs.h"
4+
#include "uart.h"
5+
#include "utils.h"
6+
static void init_common_everest(void)
7+
{
8+
reg_set(SYS_IMP_APL_HID12, BIT(46));
9+
reg_set(SYS_IMP_APL_HID3, BIT(63));
10+
reg_mask(SYS_IMP_APL_HID3, GENMASK(ULONG(62), ULONG(56)), BIT(60) | BIT(59) | BIT(58));
11+
reg_clr(SYS_IMP_APL_HID3, BIT(4));
12+
reg_set(SYS_IMP_APL_HID9, BIT(17));
13+
reg_mask(SYS_IMP_APL_HID13,
14+
HID13_POST_OFF_CYCLES_MASK | HID13_POST_ON_CYCLES_MASK | HID13_PRE_CYCLES_MASK |
15+
HID13_GROUP0_FF1_DELAY_MASK | HID13_GROUP0_FF2_DELAY_MASK |
16+
HID13_GROUP0_FF3_DELAY_MASK | HID13_GROUP0_FF4_DELAY_MASK |
17+
HID13_GROUP0_FF5_DELAY_MASK | HID13_GROUP0_FF6_DELAY_MASK |
18+
HID13_GROUP0_FF7_DELAY_MASK | HID13_RESET_CYCLES_MASK,
19+
HID13_POST_OFF_CYCLES(4) | HID13_POST_ON_CYCLES(5) | HID13_PRE_CYCLES(1) |
20+
HID13_GROUP0_FF1_DELAY(4) | HID13_GROUP0_FF2_DELAY(4) | HID13_GROUP0_FF3_DELAY(4) |
21+
HID13_GROUP0_FF4_DELAY(4) | HID13_GROUP0_FF5_DELAY(4) | HID13_GROUP0_FF6_DELAY(4) |
22+
HID13_GROUP0_FF7_DELAY(4) | HID13_RESET_CYCLES(0));
23+
reg_set(SYS_IMP_APL_HID16, BIT(54));
24+
reg_set(SYS_IMP_APL_HID18,
25+
HID18_GEXIT_EL_SPECULATION_DISABLE | HID18_GENTER_SPECULATION_DISABLE);
26+
27+
msr(SYS_IMP_APL_HID26, HID26_GROUP1_OFFSET(0xF88F65588LL) | HID26_GROUP2_OFFSET(0x3F28));
28+
reg_mask(SYS_IMP_APL_HID27,
29+
GENMASK(43, 40) | GENMASK(39, 36) | GENMASK(35, 32) | GENMASK(31, 28) |
30+
GENMASK(27, 24) | GENMASK(23, 20) | GENMASK(19, 16) | GENMASK(15, 8) |
31+
GENMASK(7, 4) | GENMASK(3, 0),
32+
BIT(40) | BIT(36) | BIT(32) | BIT(28) | BIT(24) | BIT(20) | BIT(16) | 0x2b00uL |
33+
BIT(4) | BIT(0));
34+
/* This is new to M3 and i have no idea what it is yet */
35+
reg_set(s3_0_c15_c2_3, BIT(3));
36+
reg_clr(s3_0_c15_c2_4, BIT(0) | BIT(1) | BIT(16) | BIT(17) | BIT(18) | BIT(22));
37+
}
38+
39+
void init_t6031_everest(int rev)
40+
{
41+
UNUSED(rev);
42+
msr(s3_1_c15_c1_5, 0x3uL);
43+
msr(s3_4_c15_c14_6, 0x3uL);
44+
init_common_everest();
45+
reg_set(SYS_IMP_APL_HID4, HID4_ENABLE_LFSR_STALL_LOAD_PIPE2_ISSUE);
46+
}

src/chickens_firestorm.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ void init_t8103_firestorm(int rev)
7272
reg_set(SYS_IMP_APL_HID1, HID1_ENABLE_MDSB_STALL_PIPELINE_ECO | HID1_ENABLE_BR_KILL_LIMIT);
7373

7474
if (rev >= 0x11)
75-
reg_set(SYS_IMP_APL_HID18, HID18_SPAREBIT17);
75+
reg_set(SYS_IMP_APL_HID18, HID18_PREF_REPLAY_DISABLE);
7676
}
7777

7878
void init_t6000_firestorm(int rev)
@@ -88,7 +88,7 @@ void init_t6000_firestorm(int rev)
8888
reg_set(SYS_IMP_APL_HID4,
8989
HID4_ENABLE_LFSR_STALL_LOAD_PIPE2_ISSUE | HID4_ENABLE_LFSR_STALL_STQ_REPLAY);
9090

91-
reg_set(SYS_IMP_APL_HID18, HID18_SPAREBIT17);
91+
reg_set(SYS_IMP_APL_HID18, HID18_PREF_REPLAY_DISABLE);
9292
}
9393
}
9494

@@ -108,6 +108,6 @@ void init_t6001_firestorm(int rev)
108108
if (rev >= 0x10) {
109109
reg_set(SYS_IMP_APL_HID1, HID1_ENABLE_BR_KILL_LIMIT);
110110

111-
reg_set(SYS_IMP_APL_HID18, HID18_SPAREBIT17);
111+
reg_set(SYS_IMP_APL_HID18, HID18_PREF_REPLAY_DISABLE);
112112
}
113113
}

src/chickens_sawtooth.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* SPDX-License-Identifier: MIT */
2+
3+
#include "cpu_regs.h"
4+
#include "utils.h"
5+
6+
static void init_common_sawtooth(void)
7+
{
8+
reg_set(SYS_IMP_APL_EHID0, EHID0_BLI_UNK32);
9+
}
10+
11+
void init_t6031_sawtooth(void)
12+
{
13+
init_common_sawtooth();
14+
15+
reg_mask(SYS_IMP_APL_EHID9, EHID9_DEV_2_THROTTLE_LIMIT_MASK, EHID9_DEV_2_THROTTLE_LIMIT(62));
16+
reg_set(SYS_IMP_APL_EHID9, EHID9_DEV_2_THROTTLE_ENABLE);
17+
reg_set(SYS_IMP_APL_EHID18, EHID18_BLZ_UNK34);
18+
19+
reg_mask(SYS_IMP_APL_HID5, HID5_BLZ_UNK_19_18_MASK, HID5_BLZ_UNK19);
20+
}

src/cpu_regs.h

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@
299299
#define HID11_ENABLE_FIX_UC_55719865 BIT(15)
300300
#define HID11_DISABLE_LD_NT_WIDGET BIT(59)
301301

302+
#define SYS_IMP_APL_HID12 sys_reg(3, 0, 15, 12, 0)
303+
302304
#define SYS_IMP_APL_HID13 sys_reg(3, 0, 15, 14, 0)
303305
#define HID13_POST_OFF_CYCLES(x) ((ULONG(x)))
304306
#define HID13_POST_OFF_CYCLES_MASK GENMASK(6, 0)
@@ -333,12 +335,12 @@
333335
#define HID16_ENABLE_MPX_PICK_45 BIT(61)
334336
#define HID16_ENABLE_MP_CYCLONE_7 BIT(62)
335337

336-
#define SYS_IMP_APL_HID18 sys_reg(3, 0, 15, 11, 2)
337-
#define HID18_HVC_SPECULATION_DISABLE BIT(14)
338-
#define HID18_AVL_UNK27 BIT(27)
339-
#define HID18_AVL_UNK29 BIT(29)
340-
#define HID18_SPAREBIT7 BIT(39)
341-
#define HID18_SPAREBIT17 BIT(49)
338+
#define SYS_IMP_APL_HID18 sys_reg(3, 0, 15, 11, 2)
339+
#define HID18_HVC_SPECULATION_DISABLE BIT(14)
340+
#define HID18_GEXIT_EL_SPECULATION_DISABLE BIT(27)
341+
#define HID18_GENTER_SPECULATION_DISABLE BIT(29)
342+
#define HID18_BTP_BRN_DISABLE BIT(39)
343+
#define HID18_PREF_REPLAY_DISABLE BIT(49)
342344

343345
#define SYS_IMP_APL_EHID18 sys_reg(3, 0, 15, 11, 3)
344346
#define EHID18_BLZ_UNK34 BIT(34)
@@ -401,11 +403,12 @@
401403
#define EHID20_FORCE_NONSPEC_TARGETED_TIMER_SEL(x) ((ULONG(x)) << 21)
402404
#define EHID20_FORCE_NONSPEC_TARGETED_TIMER_SEL_MASK (3UL << 21)
403405

404-
#define SYS_IMP_APL_HID21 sys_reg(3, 0, 15, 1, 3)
406+
#define SYS_IMP_APL_HID21 sys_reg(3, 0, 15, 1, 3)
407+
// In 6031's, this is marked as "wfi_full_quis"
405408
#define HID21_ENABLE_LDREX_FILL_REPLY BIT(19)
406-
#define HID21_LDQ_RTR_WAIT_FOR_OLD_ST_REL_COMPLETION BIT(33)
407-
#define HID21_DISABLE_CDP_REPLY_PURGED_TRANSACTION BIT(34)
408-
#define HID21_AVL_UNK52 BIT(52)
409+
#define HID21_LDQ_RTR_WAIT_FOR_OLD_ST_REL_COMPLETION BIT(34)
410+
#define HID21_DISABLE_CDP_REPLY_PURGED_TRANSACTION BIT(35)
411+
#define HID21_PURGE_MMU_ON_ANY_SPR_SYNC BIT(52)
409412

410413
#define SYS_IMP_APL_HID26 sys_reg(3, 0, 15, 0, 3)
411414
#define HID26_GROUP1_OFFSET(x) ((ULONG(x)) << 0)
@@ -617,3 +620,7 @@
617620
#define IPI_SR_PENDING BIT(0)
618621

619622
#define SYS_IMP_APL_IPI_CR_EL1 sys_reg(3, 5, 15, 3, 1)
623+
624+
/* Lockdown registers */
625+
#define SYS_IMP_APL_SPR_LOCKDOWN_EL2 sys_reg(3, 4, 15, 0, 5)
626+
#define SYS_IMP_APL_SPR_LOCKDOWN_EL1 sys_reg(3, 4, 15, 0, 6)

src/main.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ void run_actions(void)
113113
printf("Valid payload found\n");
114114
return;
115115
}
116-
117116
fb_set_active(true);
118117

119118
printf("No valid payload found\n");

src/mcc.c

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ static bool mcc_initialized = false;
2323
#define T6000_DCS_STRIDE 0x100000
2424
#define T6000_DCS_COUNT 4
2525

26+
#define T6031_PLANE_OFFSET 0
27+
#define T6031_PLANE_STRIDE 0x40000
28+
#define T6031_GLOBAL_OFFSET 0x100000
29+
#define T6031_DCS_OFFSET 0x400000
30+
#define T6031_DCS_STRIDE 0x200000
31+
2632
#define PLANE_TZ_MAX_REGS 4
2733

2834
struct tz_regs {
@@ -49,6 +55,14 @@ struct tz_regs t602x_tz_regs = {
4955
.enable = 0x6c8,
5056
};
5157

58+
struct tz_regs t603x_tz_regs = {
59+
.count = 4,
60+
.stride = 0x14,
61+
.start = 0x6d8,
62+
.end = 0x6dc,
63+
.enable = 0x6e4,
64+
};
65+
5266
#define PLANE_CACHE_ENABLE 0x1c00
5367
#define PLANE_CACHE_STATUS 0x1c04
5468

@@ -64,6 +78,12 @@ struct tz_regs t602x_tz_regs = {
6478
(FIELD_PREP(T6000_CACHE_STATUS_DATA_COUNT, T6000_CACHE_WAYS) | \
6579
FIELD_PREP(T6000_CACHE_STATUS_TAG_COUNT, T6000_CACHE_WAYS))
6680

81+
#define T6031_CACHE_WAYS 12
82+
#define T6031_CACHE_STATUS_MASK (T6000_CACHE_STATUS_DATA_COUNT | T6000_CACHE_STATUS_TAG_COUNT)
83+
#define T6031_CACHE_STATUS_VAL \
84+
(FIELD_PREP(T6000_CACHE_STATUS_DATA_COUNT, T6031_CACHE_WAYS) | \
85+
FIELD_PREP(T6000_CACHE_STATUS_TAG_COUNT, T6031_CACHE_WAYS))
86+
6787
#define T8103_CACHE_WAYS 16
6888
#define T8103_CACHE_STATUS_MASK (T8103_CACHE_STATUS_DATA_COUNT | T8103_CACHE_STATUS_TAG_COUNT)
6989
#define T8103_CACHE_STATUS_VAL \
@@ -134,6 +154,8 @@ int mcc_enable_cache(void)
134154
if (!mcc_initialized)
135155
return -1;
136156

157+
/* The 6030 memory controller supports setting a waymask, but the desktop chips do not appear to
158+
use it */
137159
for (int mcc = 0; mcc < mcc_count; mcc++) {
138160
for (int plane = 0; plane < mcc_regs[mcc].plane_count; plane++) {
139161
plane_write32(mcc, plane, PLANE_CACHE_ENABLE, mcc_regs[mcc].cache_enable_val);
@@ -161,7 +183,12 @@ int mcc_unmap_carveouts(void)
161183

162184
mcc_carveout_count = 0;
163185
memset(mcc_carveouts, 0, sizeof mcc_carveouts);
186+
164187
// All MCCs and planes should have identical configs
188+
// Note: For unhandled machines, the TZ regions can be found (on m1, m2, m3) by looking at
189+
// region-id-2 and region-id-4 on a booted macos, in the /chosen/carveout-memory-map DT node.
190+
// This can be used along with dumping the mcc reg space to find the correct start/end/enable
191+
// above.
165192
for (u32 i = 0; i < mcc_regs[0].tz->count; i++) {
166193
uint64_t off = mcc_regs[0].tz->stride * i;
167194
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)
291318
return 0;
292319
}
293320

321+
int mcc_init_t6031(int node, int *path)
322+
{
323+
u32 reg_len;
324+
u32 reg_offset = 3;
325+
326+
if (!adt_getprop(adt, node, "reg", &reg_len)) {
327+
printf("MCC: Failed to get reg property!\n");
328+
return -1;
329+
}
330+
331+
mcc_count = reg_len / 16 - reg_offset;
332+
333+
printf("MCC: Initializing T6031 MCCs (%d instances)...\n", mcc_count);
334+
335+
if (mcc_count > MAX_MCC_INSTANCES) {
336+
printf("MCC: Too many instances, increase MAX_MCC_INSTANCES!\n");
337+
mcc_count = MAX_MCC_INSTANCES;
338+
}
339+
340+
u32 plane_count = 0;
341+
u32 dcs_count = 0;
342+
343+
if (!ADT_GETPROP(adt, node, "dcs-count-per-amcc", &dcs_count)) {
344+
printf("MCC: Failed to get dcs count!\n");
345+
return -1;
346+
}
347+
348+
if (!ADT_GETPROP(adt, node, "plane-count-per-amcc", &plane_count)) {
349+
printf("MCC: Failed to get plane count!\n");
350+
return -1;
351+
}
352+
353+
for (int i = 0; i < mcc_count; i++) {
354+
u64 base;
355+
if (adt_get_reg(adt, path, "reg", i + reg_offset, &base, NULL)) {
356+
printf("MCC: Failed to get reg index %d!\n", i + reg_offset);
357+
return -1;
358+
}
359+
360+
mcc_regs[i].plane_base = base + T6031_PLANE_OFFSET;
361+
mcc_regs[i].plane_stride = T6031_PLANE_STRIDE;
362+
mcc_regs[i].plane_count = plane_count;
363+
364+
mcc_regs[i].global_base = base + T6031_GLOBAL_OFFSET;
365+
366+
mcc_regs[i].dcs_base = base + T6031_DCS_OFFSET;
367+
mcc_regs[i].dcs_stride = T6031_DCS_STRIDE;
368+
mcc_regs[i].dcs_count = dcs_count;
369+
370+
mcc_regs[i].cache_enable_val = 1;
371+
mcc_regs[i].cache_ways = T6031_CACHE_WAYS;
372+
mcc_regs[i].cache_status_mask = T6031_CACHE_STATUS_MASK;
373+
mcc_regs[i].cache_status_val = T6031_CACHE_STATUS_VAL;
374+
mcc_regs[i].cache_disable = 0;
375+
376+
mcc_regs[i].tz = &t603x_tz_regs;
377+
}
378+
379+
printf("MCC: Initialized T6031 MCCs (%d instances, %d planes, %d channels)\n", mcc_count,
380+
mcc_regs[0].plane_count, mcc_regs[0].dcs_count);
381+
382+
mcc_initialized = true;
383+
384+
return 0;
385+
}
386+
294387
int mcc_init(void)
295388
{
296389
int path[8];
@@ -309,8 +402,10 @@ int mcc_init(void)
309402
return mcc_init_t6000(node, path, false);
310403
} else if (adt_is_compatible(adt, node, "mcc,t6020")) {
311404
return mcc_init_t6000(node, path, true);
405+
} else if (adt_is_compatible(adt, node, "mcc,t6031")) {
406+
return mcc_init_t6031(node, path);
312407
} else {
313-
printf("MCC: Unsupported version\n");
408+
printf("MCC: Unsupported version:%s\n", adt_get_property(adt, node, "compatible")->value);
314409
return -1;
315410
}
316411
}

src/soc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#define EARLY_UART_BASE 0x39b200000
2727
#elif TARGET == T8112
2828
#define EARLY_UART_BASE 0x235200000
29+
#elif TARGET == T6034 || TARGET == T6031
30+
#define EARLY_UART_BASE 0x391200000
2931
#endif
3032

3133
#endif

0 commit comments

Comments
 (0)