diff --git a/.gitmodules b/.gitmodules index 4350a2c9b52..8367b6b5b62 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,60 +1,64 @@ [submodule "3rdparty/blobs"] path = 3rdparty/blobs - url = ../blobs.git + url = https://review.coreboot.org/blobs.git update = none ignore = dirty [submodule "util/nvidia-cbootimage"] path = util/nvidia/cbootimage - url = ../nvidia-cbootimage.git + url = https://review.coreboot.org/nvidia-cbootimage.git [submodule "vboot"] path = 3rdparty/vboot - url = ../vboot.git + url = https://review.coreboot.org/vboot.git + branch = main [submodule "arm-trusted-firmware"] path = 3rdparty/arm-trusted-firmware - url = ../arm-trusted-firmware.git + url = https://review.coreboot.org/arm-trusted-firmware.git [submodule "3rdparty/chromeec"] path = 3rdparty/chromeec - url = ../chrome-ec.git + url = https://review.coreboot.org/chrome-ec.git [submodule "libhwbase"] path = 3rdparty/libhwbase - url = ../libhwbase.git + url = https://review.coreboot.org/libhwbase.git [submodule "libgfxinit"] path = 3rdparty/libgfxinit - url = ../libgfxinit.git + url = https://review.coreboot.org/libgfxinit.git [submodule "3rdparty/fsp"] path = 3rdparty/fsp - url = ../fsp.git + url = https://review.coreboot.org/fsp.git update = none ignore = dirty [submodule "opensbi"] path = 3rdparty/opensbi - url = ../opensbi.git + url = https://review.coreboot.org/opensbi.git [submodule "intel-microcode"] path = 3rdparty/intel-microcode - url = ../intel-microcode.git + url = https://review.coreboot.org/intel-microcode.git update = none ignore = dirty [submodule "3rdparty/ffs"] path = 3rdparty/ffs - url = ../ffs.git + url = https://review.coreboot.org/ffs.git [submodule "3rdparty/amd_blobs"] path = 3rdparty/amd_blobs - url = ../amd_blobs + url = https://review.coreboot.org/amd_blobs update = none ignore = dirty [submodule "3rdparty/cmocka"] path = 3rdparty/cmocka - url = ../cmocka.git + url = https://review.coreboot.org/cmocka.git update = none [submodule "3rdparty/qc_blobs"] path = 3rdparty/qc_blobs - url = ../qc_blobs.git + url = https://review.coreboot.org/qc_blobs.git update = none ignore = dirty [submodule "3rdparty/intel-sec-tools"] path = 3rdparty/intel-sec-tools - url = ../9esec-security-tooling.git + url = https://github.com/coreboot/9esec-security-tooling.git [submodule "3rdparty/stm"] path = 3rdparty/stm - url = ../STM + url = https://review.coreboot.org/STM branch = stmpe +[submodule "3rdparty/sb-signing-utils"] + path = 3rdparty/sb-signing-utils + url = https://github.com/open-power/sb-signing-utils.git diff --git a/3rdparty/sb-signing-utils b/3rdparty/sb-signing-utils new file mode 160000 index 00000000000..591c8f53482 --- /dev/null +++ b/3rdparty/sb-signing-utils @@ -0,0 +1 @@ +Subproject commit 591c8f53482243626901e1cc8a4ae321f314040d diff --git a/Makefile.inc b/Makefile.inc index 420ce515ce3..6d36a4bd2fb 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -500,9 +500,9 @@ ifeq ($(CONFIG_DEBUG_ADA_CODE),y) ADAFLAGS_common += -gnata endif -additional-dirs := $(objutil)/cbfstool $(objutil)/ifdtool \ +additional-dirs += $(objutil)/cbfstool $(objutil)/ifdtool \ $(objutil)/options $(objutil)/amdfwtool \ - $(objutil)/cbootimage + $(objutil)/cbootimage $(objutil)/ffs export $(COREBOOT_EXPORTS) @@ -538,6 +538,8 @@ RMODTOOL:=$(objutil)/cbfstool/rmodtool IFWITOOL:=$(objutil)/cbfstool/ifwitool IFITTOOL:=$(objutil)/cbfstool/ifittool AMDCOMPRESS:=$(objutil)/cbfstool/amdcompress +ECCTOOL:=$(objutil)/ffs/ecc/ecc +SBSINGTOOLS:=$(objutil)/sb-signing-utils $(obj)/cbfstool: $(CBFSTOOL) cp $< $@ @@ -576,6 +578,18 @@ $(IFDTOOL): AMDFWTOOL:=$(objutil)/amdfwtool/amdfwtool +$(ECCTOOL): + @printf " Compile ECCTOOL\n" + cp -r $(top)/3rdparty/ffs $(objutil) + cd $(objutil)/ffs && autoreconf -i && ./configure + +$(MAKE) -C $(objutil)/ffs + +$(SBSINGTOOLS): + @printf " Compile SB SIGNING UTILS\n" + cp -r $(top)/3rdparty/sb-signing-utils $(objutil) + cd $(objutil)/sb-signing-utils && autoreconf -i -Wno-unsupported && ./configure + +$(MAKE) -C $(objutil)/sb-signing-utils + APCB_EDIT_TOOL:=$(top)/util/apcb/apcb_edit.py CBOOTIMAGE:=$(objutil)/cbootimage/cbootimage @@ -687,7 +701,7 @@ install-git-commit-clangfmt: include util/crossgcc/Makefile.inc .PHONY: tools -tools: $(objutil)/kconfig/conf $(objutil)/kconfig/toada $(CBFSTOOL) $(objutil)/cbfstool/cbfs-compression-tool $(FMAPTOOL) $(RMODTOOL) $(IFWITOOL) $(objutil)/nvramtool/nvramtool $(objutil)/sconfig/sconfig $(IFDTOOL) $(CBOOTIMAGE) $(AMDFWTOOL) $(AMDCOMPRESS) $(FUTILITY) $(BINCFG) $(IFITTOOL) $(objutil)/supermicro/smcbiosinfo +tools: $(objutil)/kconfig/conf $(objutil)/kconfig/toada $(CBFSTOOL) $(objutil)/cbfstool/cbfs-compression-tool $(FMAPTOOL) $(RMODTOOL) $(IFWITOOL) $(objutil)/nvramtool/nvramtool $(objutil)/sconfig/sconfig $(IFDTOOL) $(CBOOTIMAGE) $(AMDFWTOOL) $(AMDCOMPRESS) $(FUTILITY) $(BINCFG) $(IFITTOOL) $(objutil)/supermicro/smcbiosinfo $(ECCTOOL) $(SBSINGTOOL) ########################################################################### # Common recipes for all stages @@ -1124,7 +1138,7 @@ else RAMSTAGE= endif -$(obj)/coreboot.rom: $(obj)/coreboot.pre $(RAMSTAGE) $(CBFSTOOL) $$(INTERMEDIATE) +$(obj)/coreboot.rom: $(obj)/coreboot.pre $(RAMSTAGE) $(CBFSTOOL) $(ECCTOOL) $(SBSINGTOOLS) $$(INTERMEDIATE) @printf " CBFS $(subst $(obj)/,,$(@))\n" # The full ROM may be larger than the CBFS part, so create an empty # file (filled with \377 = 0xff) and copy the CBFS image over it. @@ -1144,6 +1158,20 @@ endif # CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE $(CBFSTOOL) $@ layout @printf " CBFSPRINT $(subst $(obj)/,,$(@))\n\n" $(CBFSTOOL) $@ print -r $(subst $(spc),$(comma),$(all-regions)) +ifeq ($(CONFIG_ARCH_PPC64),y) + cp -r $(top)/3rdparty/sb-signing-utils/test/keys /tmp + @printf " SBSIGN $(subst $(obj)/,,$(@))\n" + cd $(SBSINGTOOLS) && ./sign-with-local-keys.sh $(top)/$(objcbfs)/bootblock.bin $(top)/$(obj)/bootblock.signed 2> /dev/null + cd $(SBSINGTOOLS) && ./sign-with-local-keys.sh $(top)/$@ $(top)/$@.signed 2> /dev/null + @printf " ECC $(subst $(obj)/,,$(@))\n" + $(ECCTOOL) --inject $(top)/$@.signed --output $(top)/$@.signed.ecc --p8 + $(ECCTOOL) --inject $(top)/$@ --output $(top)/$@.ecc --p8 + @printf " ECC bootblock\n" + dd if=$(obj)/bootblock.signed of=$(obj)/bootblock.signed.pad ibs=25486 conv=sync 2> /dev/null + $(ECCTOOL) --inject $(obj)/bootblock.signed.pad --output $(obj)/bootblock.signed.ecc --p8 + rm $(obj)/bootblock.signed $(obj)/bootblock.signed.pad +endif + cbfs-files-y += $(CONFIG_CBFS_PREFIX)/romstage $(CONFIG_CBFS_PREFIX)/romstage-file := $(objcbfs)/romstage.elf diff --git a/README.md b/README.md index 14879c14842..d041f6c3b30 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ +## Contributing + +All relevant chnages to OpenPOWER Talos II should go here: +https://github.com/InsurgoTech/coreboot + coreboot README =============== diff --git a/configs/config.raptor-cs-talos-2 b/configs/config.raptor-cs-talos-2 new file mode 100644 index 00000000000..2602c416bd8 --- /dev/null +++ b/configs/config.raptor-cs-talos-2 @@ -0,0 +1 @@ +CONFIG_VENDOR_RAPTOR_CS=y diff --git a/src/arch/ppc64/Makefile.inc b/src/arch/ppc64/Makefile.inc index d1774a1d157..fd57ead1ebc 100644 --- a/src/arch/ppc64/Makefile.inc +++ b/src/arch/ppc64/Makefile.inc @@ -9,7 +9,8 @@ ppc64_asm_flags = ################################################################################ ifeq ($(CONFIG_ARCH_BOOTBLOCK_PPC64),y) -bootblock-y = bootblock.S stages.c +bootblock-y = bootblock_crt0.S +bootblock-y += arch_timer.c bootblock-y += boot.c bootblock-y += rom_media.c bootblock-y += \ @@ -34,6 +35,7 @@ endif ################################################################################ ifeq ($(CONFIG_ARCH_ROMSTAGE_PPC64),y) +romstage-y += arch_timer.c romstage-y += boot.c romstage-y += stages.c romstage-y += rom_media.c @@ -62,6 +64,7 @@ endif ################################################################################ ifeq ($(CONFIG_ARCH_RAMSTAGE_PPC64),y) +ramstage-y += arch_timer.c ramstage-y += rom_media.c ramstage-y += stages.c ramstage-y += boot.c diff --git a/src/arch/ppc64/arch_timer.c b/src/arch/ppc64/arch_timer.c new file mode 100644 index 00000000000..0dc271ff64a --- /dev/null +++ b/src/arch/ppc64/arch_timer.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +/* Refer to hostboot/src/kernel/timemgr.C */ + +/* Time base frequency is 512 MHz so 512 ticks per usec */ +#define TB_TICKS_PER_USEC 512 + +static inline uint64_t get_time_base(void) +{ + uint64_t tb = 0; + asm volatile("mfspr %0, 268" : "=r" (tb)); + return tb; +} + +static struct monotonic_counter { + int initialized; + struct mono_time time; + uint64_t last_value; +} mono_counter; + +void timer_monotonic_get(struct mono_time *mt) +{ + uint64_t current_tick; + uint64_t usecs_elapsed; + + if (!mono_counter.initialized) { + mono_counter.last_value = get_time_base(); + mono_counter.initialized = 1; + } + + current_tick = get_time_base(); + usecs_elapsed = (current_tick - mono_counter.last_value) / TB_TICKS_PER_USEC; + + /* Update current time and tick values only if a full tick occurred. */ + if (usecs_elapsed) { + mono_time_add_usecs(&mono_counter.time, usecs_elapsed); + mono_counter.last_value = current_tick; + } + + /* Save result. */ + *mt = mono_counter.time; +} diff --git a/src/arch/ppc64/bootblock.S b/src/arch/ppc64/bootblock.S deleted file mode 100644 index 106c61ad953..00000000000 --- a/src/arch/ppc64/bootblock.S +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Early initialization code for POWER8. - */ - -.section ".text._start", "ax", %progbits -.globl _start -.org 0x100, 0xff -_start: - b _start - .section ".id", "a", %progbits - - .section ".id", "a", @progbits - - .globl __id_start -__id_start: -ver: - .asciz "4" //COREBOOT_VERSION -vendor: - .asciz "qemu" //CONFIG_MAINBOARD_VENDOR -part: - .asciz "1" //CONFIG_MAINBOARD_PART_NUMBER - /* Reverse offset to the vendor id */ -.long __id_end + CONFIG_ID_SECTION_OFFSET - ver - /* Reverse offset to the vendor id */ -.long __id_end + CONFIG_ID_SECTION_OFFSET - vendor - /* Reverse offset to the part number */ -.long __id_end + CONFIG_ID_SECTION_OFFSET - part - /* of this romimage */ -.long CONFIG_ROM_SIZE - .globl __id_end - -__id_end: -.previous diff --git a/src/arch/ppc64/bootblock_crt0.S b/src/arch/ppc64/bootblock_crt0.S new file mode 100644 index 00000000000..b688b7478b7 --- /dev/null +++ b/src/arch/ppc64/bootblock_crt0.S @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Early initialization code for POWER8. + */ + +#define FIXUP_ENDIAN \ + tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \ + b $+44; /* Skip trampoline if endian is good */ \ + .long 0xa600607d; /* mfmsr r11 */ \ + .long 0x01006b69; /* xori r11,r11,1 */ \ + .long 0x00004039; /* li r10,0 */ \ + .long 0x6401417d; /* mtmsrd r10,1 */ \ + .long 0x05009f42; /* bcl 20,31,$+4 */ \ + .long 0xa602487d; /* mflr r10 */ \ + .long 0x14004a39; /* addi r10,r10,20 */ \ + .long 0xa6035a7d; /* mtsrr0 r10 */ \ + .long 0xa6037b7d; /* mtsrr1 r11 */ \ + .long 0x2400004c /* rfid */ + +/* SBE sets HRMOR to 130MB, ie 2MB into 10MB cache. Our bootblock is loaded + * 12 KB above that address - it is used as a place for interrupt vectors in + * Hostboot, but it isn't actually a part of the HBBL partition to save space + * in PNOR image. */ + +.section ".text._start", "ax", %progbits +.globl _start +_start: + /* QEMU with hb-mode=on starts at address 0x10, while hardware at 0x0. */ + nop + nop + nop + nop + FIXUP_ENDIAN + + /* Set program priority to medium */ + or %r2, %r2, %r2 + + /* Stack */ + lis %r1, _estack@ha + addi %r1, %r1, _estack@l + + /* Clear .bss section */ + /* Curently not needed, .bss is zeroed in the file. If it were to be used, + * make sure that .bss is 128B aligned (size of cache line), otherwise dcbz + * will clear (part of) .opd section! */ +/* + lis %r5, _bss@ha + addi %r5, %r5, _bss@l + lis %r6, _ebss@ha + addi %r6, %r6, _ebss@l + addi %r6, %r6, -1 +1: + dcbz 0, %r5 + addi %r5, %r5, 128 + cmpld cr7, %r5, %r6 + blt cr7, 1b +*/ + + /* Enable floating point and vector operations */ + /* Vector operations are sometimes generated for code like + * 'uint8_t x[32] = {0}', this results in an exception when vector registers + * (VEC) are not enabled. VSX (vector-scalar extension) is also enabled, + * there is no reason not to. Floating point must also be enabled for VSX. + */ + mfmsr %r3 + ori %r3, %r3, 0x2000 /* FP = 1 */ + oris %r3, %r3, 0x0280 /* VEC = 1, VSX = 1 */ + mtmsr %r3 + + /* Load official procedure descriptor address for main() */ + lis %r12, main@ha + addi %r12, %r12, main@l + + /* Load TOC pointer and jump to main() */ + ld %r2, 8(%r12) + b main diff --git a/src/arch/ppc64/include/arch/byteorder.h b/src/arch/ppc64/include/arch/byteorder.h index 24853580441..a785db4839c 100644 --- a/src/arch/ppc64/include/arch/byteorder.h +++ b/src/arch/ppc64/include/arch/byteorder.h @@ -3,6 +3,9 @@ #ifndef _BYTEORDER_H #define _BYTEORDER_H -#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 + +#define PPC_BIT(bit) (0x8000000000000000UL >> (bit)) +#define PPC_BITMASK(bs,be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) #endif /* _BYTEORDER_H */ diff --git a/src/arch/ppc64/include/arch/io.h b/src/arch/ppc64/include/arch/io.h index f8c1121f1ad..0462047a322 100644 --- a/src/arch/ppc64/include/arch/io.h +++ b/src/arch/ppc64/include/arch/io.h @@ -5,31 +5,64 @@ #include +/* Set MSB to 1 to ignore HRMOR */ +#define MMIO_GROUP0_CHIP0_LPC_BASE_ADDR 0x8006030000000000 +#define LPCHC_IO_SPACE 0xD0010000 +#define LPC_BASE_ADDR (MMIO_GROUP0_CHIP0_LPC_BASE_ADDR + LPCHC_IO_SPACE) +#define MMIO_GROUP0_CHIP0_SCOM_BASE_ADDR 0x8006030000000000 + +/* Enforce In-order Execution of I/O */ +static inline void eieio(void) +{ + asm volatile("eieio" ::: "memory"); +} + static inline void outb(uint8_t value, uint16_t port) { + asm volatile("stbcix %0, %1, %2" :: "r"(value), "b"(LPC_BASE_ADDR), "r"(port)); + eieio(); } static inline void outw(uint16_t value, uint16_t port) { + asm volatile("sthcix %0, %1, %2" :: "r"(value), "b"(LPC_BASE_ADDR), "r"(port)); + eieio(); } static inline void outl(uint32_t value, uint16_t port) { + asm volatile("stwcix %0, %1, %2" :: "r"(value), "b"(LPC_BASE_ADDR), "r"(port)); + eieio(); } static inline uint8_t inb(uint16_t port) { - return 0; + uint8_t buffer; + asm volatile("lbzcix %0, %1, %2" : "=r"(buffer) : "b"(LPC_BASE_ADDR), "r"(port)); + eieio(); + return buffer; } static inline uint16_t inw(uint16_t port) { - return 0; + uint16_t buffer; + asm volatile("lhzcix %0, %1, %2" : "=r"(buffer) : "b"(LPC_BASE_ADDR), "r"(port)); + eieio(); + return buffer; } static inline uint32_t inl(uint16_t port) { - return 0; + uint32_t buffer; + asm volatile("lwzcix %0, %1, %2" : "=r"(buffer) : "b"(LPC_BASE_ADDR), "r"(port)); + eieio(); + return buffer; +} + +static inline void report_istep(uint8_t step, uint8_t substep) +{ + outb(step, 0x81); + outb(substep, 0x82); } #endif diff --git a/src/commonlib/bsd/lz4_wrapper.c b/src/commonlib/bsd/lz4_wrapper.c index 73185a50515..a75653e9547 100644 --- a/src/commonlib/bsd/lz4_wrapper.c +++ b/src/commonlib/bsd/lz4_wrapper.c @@ -63,8 +63,22 @@ typedef uint64_t U64; #define LZ4F_MAGICNUMBER 0x184D2204 +/* Bit field endianness is implementation-defined. Use masks instead. + * https://stackoverflow.com/a/6044223 */ +#define RESERVED0 0x03 +#define HAS_CONTENT_CHECKSUM 0x04 +#define HAS_CONTENT_SIZE 0x08 +#define HAS_BLOCK_CHECKSUM 0x10 +#define INDEPENDENT_BLOCKS 0x20 +#define VERSION 0xC0 +#define VERSION_SHIFT 6 + +#define RESERVED1_2 0x8F +#define MAX_BLOCK_SIZE 0x70 + struct lz4_frame_header { uint32_t magic; + /* union { uint8_t flags; struct { @@ -76,6 +90,9 @@ struct lz4_frame_header { uint8_t version : 2; }; }; + */ + uint8_t flags; + /* union { uint8_t block_descriptor; struct { @@ -84,11 +101,18 @@ struct lz4_frame_header { uint8_t reserved2 : 1; }; }; + */ + uint8_t block_descriptor; /* + uint64_t content_size iff has_content_size is set */ /* + uint8_t header_checksum */ } __packed; +/* These fix bit order, note we still need le32toh() for proper byte order */ +#define BH_SIZE 0x7FFFFFFF +#define NOT_COMPRESSED 0x80000000 + struct lz4_block_header { + /* union { uint32_t raw; struct { @@ -96,6 +120,8 @@ struct lz4_block_header { uint32_t not_compressed : 1; }; }; + */ + uint32_t raw; /* + size bytes of data */ /* + uint32_t block_checksum iff has_block_checksum is set */ } __packed; @@ -114,16 +140,17 @@ size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn) return 0; /* input overrun */ /* We assume there's always only a single, standard frame. */ - if (le32toh(h->magic) != LZ4F_MAGICNUMBER || h->version != 1) + if (le32toh(h->magic) != LZ4F_MAGICNUMBER + || (h->flags & VERSION) != (1 << VERSION_SHIFT)) return 0; /* unknown format */ - if (h->reserved0 || h->reserved1 || h->reserved2) + if ((h->flags & RESERVED0) || (h->block_descriptor & RESERVED1_2)) return 0; /* reserved must be zero */ - if (!h->independent_blocks) + if (!(h->flags & INDEPENDENT_BLOCKS)) return 0; /* we don't support block dependency */ - has_block_checksum = h->has_block_checksum; + has_block_checksum = h->flags & HAS_BLOCK_CHECKSUM; in += sizeof(*h); - if (h->has_content_size) + if (h->flags & HAS_CONTENT_SIZE) in += sizeof(uint64_t); in += sizeof(uint8_t); } @@ -133,28 +160,28 @@ size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn) break; /* input overrun */ struct lz4_block_header b = { - { .raw = le32toh(*(const uint32_t *)in) } + .raw = le32toh(*(const uint32_t *)in) }; in += sizeof(struct lz4_block_header); - if ((size_t)(in - src) + b.size > srcn) + if ((size_t)(in - src) + (b.raw & BH_SIZE) > srcn) break; /* input overrun */ - if (!b.size) { + if (!(b.raw & BH_SIZE)) { out_size = out - dst; break; /* decompression successful */ } - if (b.not_compressed) { - size_t size = MIN((uintptr_t)b.size, (uintptr_t)dst + if (b.raw & NOT_COMPRESSED) { + size_t size = MIN((uintptr_t)(b.raw & BH_SIZE), (uintptr_t)dst + dstn - (uintptr_t)out); memcpy(out, in, size); - if (size < b.size) + if (size < (b.raw & BH_SIZE)) break; /* output overrun */ out += size; } else { /* constant folding essential, do not touch params! */ - int ret = LZ4_decompress_generic(in, out, b.size, + int ret = LZ4_decompress_generic(in, out, (b.raw & BH_SIZE), dst + dstn - out, endOnInputSize, full, 0, noDict, out, NULL, 0); if (ret < 0) @@ -162,7 +189,7 @@ size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn) out += ret; } - in += b.size; + in += (b.raw & BH_SIZE); if (has_block_checksum) in += sizeof(uint32_t); } diff --git a/src/cpu/Makefile.inc b/src/cpu/Makefile.inc index a072a8b2321..93d2d27e01e 100644 --- a/src/cpu/Makefile.inc +++ b/src/cpu/Makefile.inc @@ -7,6 +7,7 @@ subdirs-y += intel subdirs-y += ti subdirs-$(CONFIG_ARCH_X86) += x86 subdirs-$(CONFIG_CPU_QEMU_X86) += qemu-x86 +subdirs-$(CONFIG_CPU_POWER9) += power9 $(eval $(call create_class_compiler,cpu_microcode,x86_32)) ################################################################################ diff --git a/src/cpu/power9/Kconfig b/src/cpu/power9/Kconfig new file mode 100644 index 00000000000..c3a628cc343 --- /dev/null +++ b/src/cpu/power9/Kconfig @@ -0,0 +1,8 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config CPU_POWER9 + bool + select ARCH_BOOTBLOCK_PPC64 + select ARCH_VERSTAGE_PPC64 + select ARCH_ROMSTAGE_PPC64 + select ARCH_RAMSTAGE_PPC64 diff --git a/src/cpu/power9/Makefile.inc b/src/cpu/power9/Makefile.inc new file mode 100644 index 00000000000..2fe9e57a96d --- /dev/null +++ b/src/cpu/power9/Makefile.inc @@ -0,0 +1,6 @@ +## SPDX-License-Identifier: GPL-2.0-or-later + +ramstage-y += power9.c + +bootblock-y += scom.c +romstage-y += scom.c diff --git a/src/cpu/power9/power9.c b/src/cpu/power9/power9.c new file mode 100644 index 00000000000..73361fe3141 --- /dev/null +++ b/src/cpu/power9/power9.c @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include + +static void power9_cpu_init(struct device *dev) +{ +} + +static struct device_operations cpu_dev_ops = { + .init = power9_cpu_init, +}; + +// FIXME: cpu_device_id is not defined for ppc64 +// static const struct cpu_device_id cpu_table[] = { +// { 0, 0 }, +// }; + +static const struct cpu_driver driver __cpu_driver = { + .ops = &cpu_dev_ops, + // .id_table = cpu_table, +}; + +struct chip_operations cpu_power8_qemu_ops = { + CHIP_NAME("POWER9 CPU") +}; diff --git a/src/cpu/power9/scom.c b/src/cpu/power9/scom.c new file mode 100644 index 00000000000..113d047d303 --- /dev/null +++ b/src/cpu/power9/scom.c @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include // HMER +#include + +#define XSCOM_DATA_IND_READ PPC_BIT(0) +#define XSCOM_DATA_IND_COMPLETE PPC_BIT(32) +#define XSCOM_DATA_IND_ERR PPC_BITMASK(33,35) +#define XSCOM_DATA_IND_DATA PPC_BITMASK(48,63) +#define XSCOM_DATA_IND_FORM1_DATA PPC_BITMASK(12,63) +#define XSCOM_IND_MAX_RETRIES 10 + +#define XSCOM_RCVED_STAT_REG 0x00090018 +#define XSCOM_LOG_REG 0x00090012 +#define XSCOM_ERR_REG 0x00090013 + +/* + * WARNING: + * Indirect access uses the same approach as Hostboot, yet all our tests so far + * were unsuccessful. It is possible that the devices we were trying to access + * must be initialized or otherwise enabled first. Because of that we decided to + * leave it as it is for now, with heavy debugging, and return to this when we + * are sure that it doesn't work because of error in implementation. + */ +void write_scom_indirect(uint64_t reg_address, uint64_t value) +{ + uint64_t addr; + uint64_t data; + addr = reg_address & 0x7FFFFFFF; + data = reg_address & XSCOM_ADDR_IND_ADDR; + data |= value & XSCOM_ADDR_IND_DATA; + printk(BIOS_EMERG, "----------------\n"); + printk(BIOS_EMERG, "SCOM WRITE\n\n"); + /* + * Reading 0x90013 here doesn't make sense. This register reports errors in + * the most recent XSCOM access, and is cleared as soon as a new access is + * attempted, meaning we can only see that reading 0x90013 was successful. + * It is possible to read this register through 'pdbg' from BMC which + * doesn't use XSCOM, in which case 0x90013 isn't polluted. + */ + printk(BIOS_EMERG, "*0x90010 = %llX,\n*0x90011 = %llX,\n*0x90012 = %llX,\n*0x90013 = %llX\n", + read_scom_direct(0x90010), + read_scom_direct(0x90011), + read_scom_direct(0x90012), + read_scom_direct(0x90013)); + printk(BIOS_EMERG, "#hmer = %llX,\n#fail = %llX,\n#done = %llX,\n#status = %llX\n", + read_hmer(), + read_hmer() & SPR_HMER_XSCOM_FAIL, + read_hmer() & SPR_HMER_XSCOM_DONE, + read_hmer() & SPR_HMER_XSCOM_STATUS); + printk(BIOS_EMERG, "WRITING addr = %llX, data = %llX\n", addr, data); + for(unsigned int i = 0; i < 0xFFFF; ++i) { + asm volatile("nop" :::"memory"); + } + write_scom_direct(addr, data); + printk(BIOS_EMERG, "#hmer = %llX,\n#fail = %llX,\n#done = %llX,\n#status = %llX\n", + read_hmer(), + read_hmer() & SPR_HMER_XSCOM_FAIL, + read_hmer() & SPR_HMER_XSCOM_DONE, + read_hmer() & SPR_HMER_XSCOM_STATUS); + printk(BIOS_EMERG, "*0x90010 = %llX,\n*0x90011 = %llX,\n*0x90012 = %llX,\n*0x90013 = %llX\n", + read_scom_direct(0x90010), + read_scom_direct(0x90011), + read_scom_direct(0x90012), + read_scom_direct(0x90013)); + for(int retries = 0; retries < XSCOM_IND_MAX_RETRIES; ++retries) { + printk(BIOS_EMERG, "READING addr = %llX\n", addr); + for(unsigned int i = 0; i < 0xFFFF; ++i) { + asm volatile("nop" :::"memory"); + } + data = read_scom_direct(addr); + printk(BIOS_EMERG, "#hmer = %llX,\n#fail = %llX,\n#done = %llX,\n#status = %llX\n", + read_hmer(), + read_hmer() & SPR_HMER_XSCOM_FAIL, + read_hmer() & SPR_HMER_XSCOM_DONE, + read_hmer() & SPR_HMER_XSCOM_STATUS); + printk(BIOS_EMERG, "*0x90010 = %llX,\n*0x90011 = %llX,\n*0x90012 = %llX,\n*0x90013 = %llX\n", + read_scom_direct(0x90010), + read_scom_direct(0x90011), + read_scom_direct(0x90012), + read_scom_direct(0x90013)); + printk(BIOS_EMERG, "READ data = %llX\n", data); + if((data & XSCOM_DATA_IND_COMPLETE) && ((data & XSCOM_DATA_IND_ERR) == 0)) { + printk(BIOS_EMERG, "SUCCESS\n"); + printk(BIOS_EMERG, "----------------\n"); + return; + } + else if(data & XSCOM_DATA_IND_COMPLETE) { + printk(BIOS_EMERG, "FINISHED WITH ERROR\n"); + printk(BIOS_EMERG, "----------------\n"); + return; + } + } +} + +uint64_t read_scom_indirect(uint64_t reg_address) +{ + uint64_t addr; + uint64_t data = -1; + addr = reg_address & 0x7FFFFFFF; + data = XSCOM_DATA_IND_READ | (reg_address & XSCOM_ADDR_IND_ADDR); + printk(BIOS_EMERG, "----------------\n"); + printk(BIOS_EMERG, "SCOM READ\n\n"); + printk(BIOS_EMERG, "*0x90010 = %llX,\n*0x90011 = %llX,\n*0x90012 = %llX,\n*0x90013 = %llX\n", + read_scom_direct(0x90010), + read_scom_direct(0x90011), + read_scom_direct(0x90012), + read_scom_direct(0x90013)); + printk(BIOS_EMERG, "#hmer = %llX,\n#fail = %llX,\n#done = %llX,\n#status = %llX\n", + read_hmer(), + read_hmer() & SPR_HMER_XSCOM_FAIL, + read_hmer() & SPR_HMER_XSCOM_DONE, + read_hmer() & SPR_HMER_XSCOM_STATUS); + printk(BIOS_EMERG, "WRITING addr = %llX, data = %llX\n", addr, data); + for(unsigned int i = 0; i < 0xFFFF; ++i) { + asm volatile("nop" :::"memory"); + } + write_scom_direct(addr, data); + printk(BIOS_EMERG, "#hmer = %llX,\n#fail = %llX,\n#done = %llX,\n#status = %llX\n", + read_hmer(), + read_hmer() & SPR_HMER_XSCOM_FAIL, + read_hmer() & SPR_HMER_XSCOM_DONE, + read_hmer() & SPR_HMER_XSCOM_STATUS); + printk(BIOS_EMERG, "*0x90010 = %llX,\n*0x90011 = %llX,\n*0x90012 = %llX,\n*0x90013 = %llX\n", + read_scom_direct(0x90010), + read_scom_direct(0x90011), + read_scom_direct(0x90012), + read_scom_direct(0x90013)); + for(int retries = 0; retries < XSCOM_IND_MAX_RETRIES; ++retries) { + printk(BIOS_EMERG, "READING addr = %llX\n", addr); + for(unsigned int i = 0; i < 0xFFFF; ++i) { + asm volatile("nop" :::"memory"); + } + data = read_scom_direct(addr); + printk(BIOS_EMERG, "#hmer = %llX,\n#fail = %llX,\n#done = %llX,\n#status = %llX\n", + read_hmer(), + read_hmer() & SPR_HMER_XSCOM_FAIL, + read_hmer() & SPR_HMER_XSCOM_DONE, + read_hmer() & SPR_HMER_XSCOM_STATUS); + printk(BIOS_EMERG, "*0x90010 = %llX,\n*0x90011 = %llX,\n*0x90012 = %llX,\n*0x90013 = %llX\n", + read_scom_direct(0x90010), + read_scom_direct(0x90011), + read_scom_direct(0x90012), + read_scom_direct(0x90013)); + printk(BIOS_EMERG, "READ data = %llX\n", data); + printk(BIOS_EMERG, "#hmer = %llX,\n#fail = %llX,\n#done = %llX,\n#status = %llX\n", + read_hmer(), + read_hmer() & SPR_HMER_XSCOM_FAIL, + read_hmer() & SPR_HMER_XSCOM_DONE, + read_hmer() & SPR_HMER_XSCOM_STATUS); + if((data & XSCOM_DATA_IND_COMPLETE) && ((data & XSCOM_DATA_IND_ERR) == 0)) { + printk(BIOS_EMERG, "SUCCESS\n"); + printk(BIOS_EMERG, "----------------\n"); + } + else if(data & XSCOM_DATA_IND_COMPLETE) { + printk(BIOS_EMERG, "FINISHED WITH ERROR\n"); + printk(BIOS_EMERG, "----------------\n"); + } + } + + return data & XSCOM_DATA_IND_DATA; +} + +/* This function should be rarely called, don't make it inlined */ +void reset_scom_engine(void) +{ + /* + * With cross-CPU SCOM accesses, first register should be cleared on the + * executing CPU, the other two on target CPU. In that case it may be + * necessary to do the remote writes in assembly directly to skip checking + * HMER and possibly end in a loop. + */ + write_scom_direct(XSCOM_RCVED_STAT_REG, 0); + write_scom_direct(XSCOM_LOG_REG, 0); + write_scom_direct(XSCOM_ERR_REG, 0); + eieio(); +} diff --git a/src/drivers/uart/Kconfig b/src/drivers/uart/Kconfig index 41b870fbf78..beba4012e2f 100644 --- a/src/drivers/uart/Kconfig +++ b/src/drivers/uart/Kconfig @@ -5,7 +5,7 @@ config DRIVERS_UART_8250IO # FIXME: Shouldn't have a prompt, should default to n, and # should be selected by boards that have it instead. bool "Serial port on SuperIO" - depends on ARCH_X86 + depends on ARCH_X86 || ARCH_PPC64 default n if DRIVERS_UART_8250MEM || HAVE_UART_SPECIAL default n if NO_UART_ON_SUPERIO default y diff --git a/src/include/cpu/power/istep_8.h b/src/include/cpu/power/istep_8.h new file mode 100644 index 00000000000..714a34c0968 --- /dev/null +++ b/src/include/cpu/power/istep_8.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +#define XBUS_PHY_FIR_ACTION0 (0x0000000000000000ULL) +#define XBUS_PHY_FIR_ACTION1 (0x2068680000000000ULL) +#define XBUS_PHY_FIR_MASK (0xDF9797FFFFFFC000ULL) + +#define ATTR_PROC_FABRIC_X_LINKS_CNFG (1) + +#define FBC_IOE_TL_FIR_ACTION0 (0x0000000000000000ULL) +#define FBC_IOE_TL_FIR_ACTION1 (0x0049000000000000ULL) + +#define FBC_IOE_TL_FIR_MASK (0xFF24F0303FFFF11FULL) +#define FBC_IOE_TL_FIR_MASK_X0_NF (0x00C00C0C00000880ULL) + +#define FBC_IOE_DL_FIR_ACTION0 (0) +#define FBC_IOE_DL_FIR_ACTION1 (0x303c00000001ffc) +#define FBC_IOE_DL_FIR_MASK (0xfcfc3fffffffe003) + +// Power Bus PB West Mode Configuration Register +#define PB_WEST_MODE_CFG_REG (0x501180A) +// Power Bus PB CENT FIR Register +#define PB_CENT_SM0_PB_CENT_FIR_REG (0x5011C00) +// Power Bus PB CENT Mode Register +#define PB_CENT_MODE_CFG_REG (0x5011C0A) +// Power Bus PB CENT GP command RATE DP0 Register +#define PB_CENT_GP_COMMAND_RATE_DP0_REG (0x5011C26) +// Power Bus PB CENT GP command RATE DP1 Register +#define PB_CENT_GP_COMMAND_RATE_DP1_REG (0x5011C27) +// Power Bus PB CENT RGP command RATE DP0 Register +#define PB_CENT_RGP_COMMAND_RATE_DP0_REG (0x5011C28) +// Power Bus PB CENT RGP command RATE DP1 Register +#define PB_CENT_RGP_COMMAND_RATE_DP1_REG (0x5011C29) +// Power Bus PB CENT SP command RATE DP0 Register +#define PB_CENT_SP_COMMAND_RATE_DP0_REG (0x5011C2A) +// Power Bus PB CENT SP command RATE DP1 Register +#define PB_CENT_SP_COMMAND_RATE_DP1_REG (0x5011C2B) +// Power Bus PB East Mode Configuration Register +#define PB_EAST_MODE_CFG_REG (0x501200A) +// Power Bus PBEN IOX Domain FIR0 Mask Register +#define PU_PB_IOE_FIR_MASK_REG (0x5013403) +// Power Bus PBEN IOX Domain FIR Action 0 Register +#define PU_PB_IOE_FIR_ACTION0_REG (0x5013406) +// Power Bus PBEN IOX Domain FIR Action 1 Register +#define PU_PB_IOE_FIR_ACTION1_REG (0x5013407) +// Power bus Electrical Framer/Parser 01 Configuration Register +#define PB_ELE_PB_FRAMER_PARSER_01_CFG_REG (0x501340A) +// Power Bus Electrical Framer/Parser 23 Configuration Register +#define PB_ELE_PB_FRAMER_PARSER_23_CFG_REG (0x501340B) +// Power Bus Electrical Framer/Parser 45 Configuration Register +#define PB_ELE_PB_FRAMER_PARSER_45_CFG_REG (0x501340C) +// Power Bus Electrical Link Data Buffer 01 Configuration Register +#define PB_ELE_PB_DATA_BUFF_01_CFG_REG (0x5013410) +// Power Bus Electrical Link Data Buffer 23 Configuration Register +#define PB_ELE_PB_DATA_BUFF_23_CFG_REG (0x5013411) +// Power Bus Electrical Link Data Buffer 45 Configuration Register +#define PB_ELE_PB_DATA_BUFF_45_CFG_REG (0x5013412) +// Power Bus Electrical Miscellaneous Configuration Register +#define PB_ELE_MISC_CFG_REG (0x5013423) +// Power Bus Electrical Link Trace Configuration Register +#define PB_ELE_LINK_TRACE_CFG_REG (0x5013424) +// ELL FIR Mask Register +#define XBUS_LL0_IOEL_FIR_MASK_REG (0x6011803) +// ELL FIR Action 0 Register +#define XBUS_LL0_IOEL_FIR_ACTION0_REG (0x6011806) +// ELL FIR Action 1 Register +#define XBUS_LL0_IOEL_FIR_ACTION1_REG (0x6011807) +// Power Bus ELL Configuration Register +#define PB_ELL_CFG_REG (0x601180A) +// Power Bus ELL Replay Threshold Register +#define PB_ELL_REPLAY_TRESHOLD_REG (0x6011818) +// Power Bus ELL SL ECC Threshold Register +#define PB_ELL_SL_ECC_TRESHOLD_REG (0x6011819) +#define XBUS_FIR_MASK_REG (0x6010C03) +#define XBUS_FIR_ACTION0_REG (0x6010C06) +#define XBUS_FIR_ACTION1_REG (0x6010C07) + +void istep_8_10(void); +void p9_io_xbus_scominit(const uint8_t); +void p9_xbus_g0_scom(void); +void p9_xbus_g1_scom(void); + +void istep_8_9(void); +void p9_fbc_ioe_dl_scom(void); +void p9_fbc_ioe_tl_scom(void); +void p9_fbc_no_hp_scom(void); +void ioe_tl_fir(void); +void ioel_fir(void); + + diff --git a/src/include/cpu/power/scom.h b/src/include/cpu/power/scom.h new file mode 100644 index 00000000000..8a30387e53d --- /dev/null +++ b/src/include/cpu/power/scom.h @@ -0,0 +1,221 @@ +#ifndef CPU_PPC64_SCOM_H +#define CPU_PPC64_SCOM_H + +#include // PPC_BIT(), PPC_BITMASK() + +// 32b SCOM address: +// +// 8 7 6 5 4 3 2 1 +// +// |0 1 2 3| |4 5 6 7| |8 9 10 11| |12 13 14 15| |16 17 18 19| |20 21 22 23| |24 25 26 27| |28 29 30 31| +// {A}{ B } { C } { D }{ E }{ F } +// +// A - Is multiCast if bit 1 = 0x1 +// B - Contains Chiplet ID (6 bits) [2:7] +// C - Contains Port Number (4 bits) [12:15] +// D - Ring (4 bits) [18:21] +// E - Sat ID (4 bits) [22:25] +// F - Sat Offset (6 bits) [26:31] +// +// For 64b SCOM address all of the fields are shifted 32b to the right: +// A - Is multiCast if bit 33 = 0x1 +// B - Contains Chiplet ID (6 bits) [34:39] +// C - Contains Port Number (4 bits) [44:47] +// D - Ring (4 bits) [50:53] +// E - Sat ID (4 bits) [54:57] +// F - Sat Offset (6 bits) [58:63] +// Higher bits specify indirect address + +#define XSCOM_ADDR_IND_FLAG PPC_BIT(0) +#define XSCOM_ADDR_IND_ADDR PPC_BITMASK(11,31) +#define XSCOM_ADDR_IND_DATA PPC_BITMASK(48,63) + +#ifndef __ASSEMBLER__ +#include +#include +#include + +// TODO: these are probably specific to POWER9 +typedef enum +{ + PIB_CHIPLET_ID = 0x00, ///< PIB chiplet + PERV_CHIPLET_ID = 0x01, ///< TP chiplet + N0_CHIPLET_ID = 0x02, ///< Nest0 (North) chiplet + N1_CHIPLET_ID = 0x03, ///< Nest1 (East) chiplet + N2_CHIPLET_ID = 0x04, ///< Nest2 (South) chiplet + N3_CHIPLET_ID = 0x05, ///< Nest3 (West) chiplet + XB_CHIPLET_ID = 0x06, ///< XBus chiplet + MC01_CHIPLET_ID = 0x07, ///< MC01 (West) chiplet + MC23_CHIPLET_ID = 0x08, ///< MC23 (East) chiplet + OB0_CHIPLET_ID = 0x09, ///< OBus0 chiplet + OB1_CHIPLET_ID = 0x0A, ///< OBus1 chiplet (Cumulus only) + OB2_CHIPLET_ID = 0x0B, ///< OBus2 chiplet (Cumulus only) + OB3_CHIPLET_ID = 0x0C, ///< OBus3 chiplet + PCI0_CHIPLET_ID = 0x0D, ///< PCIe0 chiplet + PCI1_CHIPLET_ID = 0x0E, ///< PCIe1 chiplet + PCI2_CHIPLET_ID = 0x0F, ///< PCIe2 chiplet + EP00_CHIPLET_ID = 0x10, ///< Quad0 chiplet (EX0/1) + EP01_CHIPLET_ID = 0x11, ///< Quad1 chiplet (EX2/3) + EP02_CHIPLET_ID = 0x12, ///< Quad2 chiplet (EX4/5) + EP03_CHIPLET_ID = 0x13, ///< Quad3 chiplet (EX6/7) + EP04_CHIPLET_ID = 0x14, ///< Quad4 chiplet (EX8/9) + EP05_CHIPLET_ID = 0x15, ///< Quad5 chiplet (EX10/11) + EC00_CHIPLET_ID = 0x20, ///< Core0 chiplet (Quad0, EX0, C0) + EC01_CHIPLET_ID = 0x21, ///< Core1 chiplet (Quad0, EX0, C1) + EC02_CHIPLET_ID = 0x22, ///< Core2 chiplet (Quad0, EX1, C0) + EC03_CHIPLET_ID = 0x23, ///< Core3 chiplet (Quad0, EX1, C1) + EC04_CHIPLET_ID = 0x24, ///< Core4 chiplet (Quad1, EX2, C0) + EC05_CHIPLET_ID = 0x25, ///< Core5 chiplet (Quad1, EX2, C1) + EC06_CHIPLET_ID = 0x26, ///< Core6 chiplet (Quad1, EX3, C0) + EC07_CHIPLET_ID = 0x27, ///< Core7 chiplet (Quad1, EX3, C1) + EC08_CHIPLET_ID = 0x28, ///< Core8 chiplet (Quad2, EX4, C0) + EC09_CHIPLET_ID = 0x29, ///< Core9 chiplet (Quad2, EX4, C1) + EC10_CHIPLET_ID = 0x2A, ///< Core10 chiplet (Quad2, EX5, C0) + EC11_CHIPLET_ID = 0x2B, ///< Core11 chiplet (Quad2, EX5, C1) + EC12_CHIPLET_ID = 0x2C, ///< Core12 chiplet (Quad3, EX6, C0) + EC13_CHIPLET_ID = 0x2D, ///< Core13 chiplet (Quad3, EX6, C1) + EC14_CHIPLET_ID = 0x2E, ///< Core14 chiplet (Quad3, EX7, C0) + EC15_CHIPLET_ID = 0x2F, ///< Core15 chiplet (Quad3, EX7, C1) + EC16_CHIPLET_ID = 0x30, ///< Core16 chiplet (Quad4, EX8, C0) + EC17_CHIPLET_ID = 0x31, ///< Core17 chiplet (Quad4, EX8, C1) + EC18_CHIPLET_ID = 0x32, ///< Core18 chiplet (Quad4, EX9, C0) + EC19_CHIPLET_ID = 0x33, ///< Core19 chiplet (Quad4, EX9, C1) + EC20_CHIPLET_ID = 0x34, ///< Core20 chiplet (Quad5, EX10, C0) + EC21_CHIPLET_ID = 0x35, ///< Core21 chiplet (Quad5, EX10, C1) + EC22_CHIPLET_ID = 0x36, ///< Core22 chiplet (Quad5, EX11, C0) + EC23_CHIPLET_ID = 0x37 ///< Core23 chiplet (Quad5, EX11, C1) +} chiplet_id_t; + +static const chiplet_id_t mcs_to_nest[] = +{ + [MC01_CHIPLET_ID] = N3_CHIPLET_ID, + [MC23_CHIPLET_ID] = N1_CHIPLET_ID, +}; + +void reset_scom_engine(void); + +static uint64_t read_scom_direct(uint64_t reg_address) +{ + uint64_t val; + uint64_t hmer = 0; + do { + /* + * Clearing HMER on every SCOM access seems to slow down CCS up + * to a point where it starts hitting timeout on "less ideal" + * DIMMs for write centering. Clear it only if this do...while + * executes more than once. + */ + if ((hmer & SPR_HMER_XSCOM_STATUS) == SPR_HMER_XSCOM_OCCUPIED) + clear_hmer(); + + eieio(); + asm volatile( + "ldcix %0, %1, %2": + "=r"(val): + "b"(MMIO_GROUP0_CHIP0_SCOM_BASE_ADDR), + "r"(reg_address << 3)); + eieio(); + hmer = read_hmer(); + } while ((hmer & SPR_HMER_XSCOM_STATUS) == SPR_HMER_XSCOM_OCCUPIED); + + if (hmer & SPR_HMER_XSCOM_STATUS) { + reset_scom_engine(); + /* + * All F's are returned in case of error, but code polls for a set bit + * after changes that can make such error appear (e.g. clock settings). + * Return 0 so caller won't have to test for all F's in that case. + */ + return 0; + } + return val; +} + +static void write_scom_direct(uint64_t reg_address, uint64_t data) +{ + uint64_t hmer = 0; + do { + /* See comment in read_scom_direct() */ + if ((hmer & SPR_HMER_XSCOM_STATUS) == SPR_HMER_XSCOM_OCCUPIED) + clear_hmer(); + + eieio(); + asm volatile( + "stdcix %0, %1, %2":: + "r"(data), + "b"(MMIO_GROUP0_CHIP0_SCOM_BASE_ADDR), + "r"(reg_address << 3)); + eieio(); + hmer = read_hmer(); + } while ((hmer & SPR_HMER_XSCOM_STATUS) == SPR_HMER_XSCOM_OCCUPIED); + + if (hmer & SPR_HMER_XSCOM_STATUS) + reset_scom_engine(); +} + +uint64_t read_scom_indirect(uint64_t reg_address); +void write_scom_indirect(uint64_t reg_address, uint64_t data); + +static inline void write_scom(uint64_t addr, uint64_t data) +{ + if (addr & XSCOM_ADDR_IND_FLAG) + write_scom_indirect(addr, data); + else + write_scom_direct(addr, data); +} + +static inline uint64_t read_scom(uint64_t addr) +{ + if (addr & XSCOM_ADDR_IND_FLAG) + return read_scom_indirect(addr); + else + return read_scom_direct(addr); +} + +static inline void scom_and_or(uint64_t addr, uint64_t and, uint64_t or) +{ + uint64_t data = read_scom(addr); + write_scom(addr, (data & and) | or); +} + +static inline void scom_and(uint64_t addr, uint64_t and) +{ + scom_and_or(addr, and, 0); +} + +static inline void scom_or(uint64_t addr, uint64_t or) +{ + scom_and_or(addr, ~0, or); +} + +static inline void write_scom_for_chiplet(chiplet_id_t chiplet, uint64_t addr, uint64_t data) +{ + addr &= ~PPC_BITMASK(34,39); + addr |= ((chiplet & 0x3F) << 24); + write_scom(addr, data); +} + +static inline uint64_t read_scom_for_chiplet(chiplet_id_t chiplet, uint64_t addr) +{ + addr &= ~PPC_BITMASK(34,39); + addr |= ((chiplet & 0x3F) << 24); + return read_scom(addr); +} + +static inline void scom_and_or_for_chiplet(chiplet_id_t chiplet, uint64_t addr, uint64_t and, uint64_t or) +{ + uint64_t data = read_scom_for_chiplet(chiplet, addr); + write_scom_for_chiplet(chiplet, addr, (data & and) | or); +} + +static inline void scom_and_for_chiplet(chiplet_id_t chiplet, uint64_t addr, uint64_t and) +{ + scom_and_or_for_chiplet(chiplet, addr, and, 0); +} + +static inline void scom_or_for_chiplet(chiplet_id_t chiplet, uint64_t addr, uint64_t or) +{ + scom_and_or_for_chiplet(chiplet, addr, ~0, or); +} + +#endif /* __ASSEMBLER__ */ +#endif /* CPU_PPC64_SCOM_H */ diff --git a/src/include/cpu/power/scom_registers.h b/src/include/cpu/power/scom_registers.h new file mode 100644 index 00000000000..2aedfccab3e --- /dev/null +++ b/src/include/cpu/power/scom_registers.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define PB_WEST_MODE_CFG_REG (0x501180A) // Power Bus PB West Mode Configuration Register +#define PB_CENT_SM0_PB_CENT_FIR_REG (0x5011C00) // Power Bus PB CENT FIR Register +#define PB_CENT_MODE_CFG_REG (0x5011C0A) // Power Bus PB CENT Mode Register +#define PB_CENT_GP_COMMAND_RATE_DP0_REG (0x5011C26) // Power Bus PB CENT GP command RATE DP0 Register +#define PB_CENT_GP_COMMAND_RATE_DP1_REG (0x5011C27) // Power Bus PB CENT GP command RATE DP1 Register +#define PB_CENT_RGP_COMMAND_RATE_DP0_REG (0x5011C28) // Power Bus PB CENT RGP command RATE DP0 Register +#define PB_CENT_RGP_COMMAND_RATE_DP1_REG (0x5011C29) // Power Bus PB CENT RGP command RATE DP1 Register +#define PB_CENT_SP_COMMAND_RATE_DP0_REG (0x5011C2A) // Power Bus PB CENT SP command RATE DP0 Register +#define PB_CENT_SP_COMMAND_RATE_DP1_REG (0x5011C2B) // Power Bus PB CENT SP command RATE DP1 Register +#define PB_EAST_MODE_CFG_REG (0x501200A) // Power Bus PB East Mode Configuration Register +#define PU_PB_IOE_FIR_MASK_REG (0x5013403) // Power Bus PBEN IOX Domain FIR0 Mask Register +#define PU_PB_IOE_FIR_ACTION0_REG (0x5013406) // Power Bus PBEN IOX Domain FIR Action 0 Register +#define PU_PB_IOE_FIR_ACTION1_REG (0x5013407) // Power Bus PBEN IOX Domain FIR Action 1 Register +#define PB_ELE_PB_FRAMER_PARSER_01_CFG_REG (0x501340A) // Power bus Electrical Framer/Parser 01 Configuration Register +#define PB_ELE_PB_FRAMER_PARSER_23_CFG_REG (0x501340B) // Power Bus Electrical Framer/Parser 23 Configuration Register +#define PB_ELE_PB_FRAMER_PARSER_45_CFG_REG (0x501340C) // Power Bus Electrical Framer/Parser 45 Configuration Register +#define PB_ELE_PB_DATA_BUFF_01_CFG_REG (0x5013410) // Power Bus Electrical Link Data Buffer 01 Configuration Register +#define PB_ELE_PB_DATA_BUFF_23_CFG_REG (0x5013411) // Power Bus Electrical Link Data Buffer 23 Configuration Register +#define PB_ELE_PB_DATA_BUFF_45_CFG_REG (0x5013412) // Power Bus Electrical Link Data Buffer 45 Configuration Register +#define PB_ELE_MISC_CFG_REG (0x5013423) // Power Bus Electrical Miscellaneous Configuration Register +#define PB_ELE_LINK_TRACE_CFG_REG (0x5013424) // Power Bus Electrical Link Trace Configuration Register +#define XBUS_LL0_IOEL_FIR_MASK_REG (0x6011803) // ELL FIR Mask Register +#define XBUS_LL0_IOEL_FIR_ACTION0_REG (0x6011806) // ELL FIR Action 0 Register +#define XBUS_LL0_IOEL_FIR_ACTION1_REG (0x6011807) // ELL FIR Action 1 Register +#define PB_ELL_CFG_REG (0x601180A) // Power Bus ELL Configuration Register +#define PB_ELL_REPLAY_TRESHOLD_REG (0x6011818) // Power Bus ELL Replay Threshold Register +#define PB_ELL_SL_ECC_TRESHOLD_REG (0x6011819) // Power Bus ELL SL ECC Threshold Register +#define XBUS_FIR_MASK_REG (0x6010C03) +#define XBUS_FIR_ACTION0_REG (0x6010C06) +#define XBUS_FIR_ACTION1_REG (0x6010C07) diff --git a/src/include/cpu/power/spr.h b/src/include/cpu/power/spr.h new file mode 100644 index 00000000000..97a3399e911 --- /dev/null +++ b/src/include/cpu/power/spr.h @@ -0,0 +1,47 @@ +#ifndef CPU_PPC64_SPR_H +#define CPU_PPC64_SPR_H + +#include // PPC_BIT() + +#define SPR_HMER 0x150 +/* Bits in HMER/HMEER */ +#define SPR_HMER_MALFUNCTION_ALERT PPC_BIT(0) +#define SPR_HMER_PROC_RECV_DONE PPC_BIT(2) +#define SPR_HMER_PROC_RECV_ERROR_MASKED PPC_BIT(3) +#define SPR_HMER_TFAC_ERROR PPC_BIT(4) +#define SPR_HMER_TFMR_PARITY_ERROR PPC_BIT(5) +#define SPR_HMER_XSCOM_FAIL PPC_BIT(8) +#define SPR_HMER_XSCOM_DONE PPC_BIT(9) +#define SPR_HMER_PROC_RECV_AGAIN PPC_BIT(11) +#define SPR_HMER_WARN_RISE PPC_BIT(14) +#define SPR_HMER_WARN_FALL PPC_BIT(15) +#define SPR_HMER_SCOM_FIR_HMI PPC_BIT(16) +#define SPR_HMER_TRIG_FIR_HMI PPC_BIT(17) +#define SPR_HMER_HYP_RESOURCE_ERR PPC_BIT(20) +#define SPR_HMER_XSCOM_STATUS PPC_BITMASK(21,23) +#define SPR_HMER_XSCOM_OCCUPIED PPC_BIT(23) + +#ifndef __ASSEMBLER__ +#include + +static inline uint64_t read_hmer(void) +{ + uint64_t val; + asm volatile("mfspr %0,%1" : "=r"(val) : "i"(SPR_HMER) : "memory"); + return val; +} + +static inline void clear_hmer(void) +{ + asm volatile("mtspr %0, %1" :: "i"(SPR_HMER), "r"(0) : "memory"); +} + +static inline uint64_t read_msr(void) +{ + uint64_t val; + asm volatile("mfmsr %0" : "=r"(val) :: "memory"); + return val; +} + +#endif /* __ASSEMBLER__ */ +#endif /* CPU_PPC64_SPR_H */ diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index d27550576af..9aea33d8589 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -363,8 +363,7 @@ int cbfs_prog_stage_load(struct prog *pstage) foffset = 0; foffset += sizeof(stage); - /* cbfs_stage fields are written in little endian despite the other - cbfs data types being encoded in big endian. */ + /* Convert cbfs_stage fields to host endian. */ stage.compression = read_le32(&stage.compression); stage.entry = read_le64(&stage.entry); stage.load = read_le64(&stage.load); diff --git a/src/lib/fmap.c b/src/lib/fmap.c index 2abe138cdd7..5adf6b69f79 100644 --- a/src/lib/fmap.c +++ b/src/lib/fmap.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "fmap_config.h" @@ -49,7 +50,8 @@ static void report(const struct fmap *fmap) print_once(BIOS_DEBUG, "FMAP: Found \"%s\" version %d.%d at %#x.\n", fmap->name, fmap->ver_major, fmap->ver_minor, FMAP_OFFSET); print_once(BIOS_DEBUG, "FMAP: base = %#llx size = %#x #areas = %d\n", - (long long)fmap->base, fmap->size, fmap->nareas); + (long long)le64toh(fmap->base), le32toh(fmap->size), + le16toh(fmap->nareas)); fmap_print_once = 1; } @@ -185,10 +187,10 @@ int fmap_locate_area(const char *name, struct region *ar) } printk(BIOS_DEBUG, "FMAP: area %s found @ %x (%d bytes)\n", - name, area->offset, area->size); + name, le32toh(area->offset), le32toh(area->size)); - ar->offset = area->offset; - ar->size = area->size; + ar->offset = le32toh(area->offset); + ar->size = le32toh(area->size); rdev_munmap(&fmrd, area); @@ -220,8 +222,8 @@ int fmap_find_region_name(const struct region * const ar, if (area == NULL) return -1; - if ((ar->offset != area->offset) || - (ar->size != area->size)) { + if ((ar->offset != le32toh(area->offset)) || + (ar->size != le32toh(area->size))) { rdev_munmap(&fmrd, area); offset += sizeof(struct fmap_area); continue; diff --git a/src/mainboard/raptor-cs/Kconfig b/src/mainboard/raptor-cs/Kconfig new file mode 100644 index 00000000000..7f916bbaf37 --- /dev/null +++ b/src/mainboard/raptor-cs/Kconfig @@ -0,0 +1,15 @@ +if VENDOR_RAPTOR_CS + +choice + prompt "Mainboard model" + +source "src/mainboard/raptor-cs/*/Kconfig.name" + +endchoice + +source "src/mainboard/raptor-cs/*/Kconfig" + +config MAINBOARD_VENDOR + default "Raptor Computing Systems" + +endif # VENDOR_RAPTOR_CS diff --git a/src/mainboard/raptor-cs/Kconfig.name b/src/mainboard/raptor-cs/Kconfig.name new file mode 100644 index 00000000000..7f9d8d6b9bd --- /dev/null +++ b/src/mainboard/raptor-cs/Kconfig.name @@ -0,0 +1,2 @@ +config VENDOR_RAPTOR_CS + bool "Raptor Computing Systems" diff --git a/src/mainboard/raptor-cs/talos-2/Kconfig b/src/mainboard/raptor-cs/talos-2/Kconfig new file mode 100644 index 00000000000..066849c80af --- /dev/null +++ b/src/mainboard/raptor-cs/talos-2/Kconfig @@ -0,0 +1,46 @@ +## SPDX-License-Identifier: GPL-2.0-only + +if BOARD_RAPTOR_CS_TALOS_2 + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select CPU_POWER9 + select SOC_IBM_POWER9 + select BOARD_ROMSIZE_KB_16384 + select ARCH_BOOTBLOCK_PPC64 + select ARCH_VERSTAGE_PPC64 + select ARCH_ROMSTAGE_PPC64 + select ARCH_RAMSTAGE_PPC64 + select SUPERIO_ASPEED_AST2400 + select BOOT_DEVICE_NOT_SPI_FLASH + select MISSING_BOARD_RESET + +config MEMLAYOUT_LD_FILE + string + default "src/mainboard/raptor-cs/talos-2/memlayout.ld" + +config MAINBOARD_DIR + string + default "raptor-cs/talos-2" + +config MAINBOARD_PART_NUMBER + string + default "Talos II" + +config MAX_CPUS + int + default 1 + +config CBFS_SIZE + hex + default 0x1000000 + +config MAINBOARD_VENDOR + string + default "Raptor CS" + +config DRAM_SIZE_MB + int + default 32768 + +endif # BOARD_RAPTOR_CS_TALOS_2 diff --git a/src/mainboard/raptor-cs/talos-2/Kconfig.name b/src/mainboard/raptor-cs/talos-2/Kconfig.name new file mode 100644 index 00000000000..8a75417628d --- /dev/null +++ b/src/mainboard/raptor-cs/talos-2/Kconfig.name @@ -0,0 +1,2 @@ +config BOARD_RAPTOR_CS_TALOS_2 + bool "Talos II" diff --git a/src/mainboard/raptor-cs/talos-2/Makefile.inc b/src/mainboard/raptor-cs/talos-2/Makefile.inc new file mode 100644 index 00000000000..3e69e6226a4 --- /dev/null +++ b/src/mainboard/raptor-cs/talos-2/Makefile.inc @@ -0,0 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + +bootblock-y += bootblock.c +romstage-y += cbmem.c +romstage-y += romstage.c diff --git a/src/mainboard/raptor-cs/talos-2/board_info.txt b/src/mainboard/raptor-cs/talos-2/board_info.txt new file mode 100644 index 00000000000..aa2269185be --- /dev/null +++ b/src/mainboard/raptor-cs/talos-2/board_info.txt @@ -0,0 +1,2 @@ +Board name: Raptor CS Talos II +Category: desktop diff --git a/src/mainboard/raptor-cs/talos-2/bootblock.c b/src/mainboard/raptor-cs/talos-2/bootblock.c new file mode 100644 index 00000000000..6fe764938d3 --- /dev/null +++ b/src/mainboard/raptor-cs/talos-2/bootblock.c @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include + +void mainboard_post(uint8_t value) +{ + outb(value, 0x80); +} + +void bootblock_mainboard_early_init(void) +{ + struct config_data vuart_init[] = { + /* Activate VUART */ + [Step1] = { + .type = SIO, + .base = 0, + .reg = ACT_REG, + .and = 0, + .or = ACTIVATE_VALUE + }, + /* Configure IRQ level as low */ + [Step2] = { + .type = MEM, + .base = ASPEED_VUART_BASE, + .reg = 0x20, + .and = ~2, + .or = 0 + }, + /* Set the SerIRQ IRQ 4 */ + [Step3] = { + .type = MEM, + .base = ASPEED_VUART_BASE, + .reg = 0x24, + .and = ~0xf0, + .or = (4 << 4) + }, + /* Configure base address low */ + [Step4] = { + .type = MEM, + .base = ASPEED_VUART_BASE, + .reg = 0x28, + .and = 0, + .or = CONFIG_TTYS0_BASE & 0xff + }, + /* Configure base address high */ + [Step5] = { + .type = MEM, + .base = ASPEED_VUART_BASE, + .reg = 0x2c, + .and = 0, + .or = (CONFIG_TTYS0_BASE >> 8) & 0xff + }, + }; + + const pnp_devfn_t serial_dev = PNP_DEV(0x2e, AST2400_ILPC2AHB); + aspeed_early_config(serial_dev, vuart_init, ARRAY_SIZE(vuart_init)); +} diff --git a/src/mainboard/raptor-cs/talos-2/cbmem.c b/src/mainboard/raptor-cs/talos-2/cbmem.c new file mode 100644 index 00000000000..15c20f8de42 --- /dev/null +++ b/src/mainboard/raptor-cs/talos-2/cbmem.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +void *cbmem_top_chipset(void) +{ + /* Top of cbmem is at lowest usable DRAM address below 4GiB. */ + /* For now, last 1M of 4G */ + void *ptr = (void *) ((1ULL << 32) - 1048576); + return ptr; +} diff --git a/src/mainboard/raptor-cs/talos-2/devicetree.cb b/src/mainboard/raptor-cs/talos-2/devicetree.cb new file mode 100644 index 00000000000..7ea6247070e --- /dev/null +++ b/src/mainboard/raptor-cs/talos-2/devicetree.cb @@ -0,0 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + +chip cpu/power9 + device cpu_cluster 0 on end +end diff --git a/src/mainboard/raptor-cs/talos-2/mainboard.c b/src/mainboard/raptor-cs/talos-2/mainboard.c new file mode 100644 index 00000000000..54ae445b5fd --- /dev/null +++ b/src/mainboard/raptor-cs/talos-2/mainboard.c @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +static void mainboard_enable(struct device *dev) +{ + + if (!dev) { + die("No dev0; die\n"); + } + + /* Where does RAM live? */ + ram_resource(dev, 0, 2048, 32768); + cbmem_recovery(0); +} + +struct chip_operations mainboard_ops = { + .enable_dev = mainboard_enable, +}; diff --git a/src/mainboard/raptor-cs/talos-2/memlayout.ld b/src/mainboard/raptor-cs/talos-2/memlayout.ld new file mode 100644 index 00000000000..c5136b9d14e --- /dev/null +++ b/src/mainboard/raptor-cs/talos-2/memlayout.ld @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +#include + +// TODO: fill in these blanks for Power9. +SECTIONS +{ + DRAM_START(0x0) + BOOTBLOCK(0, 64K) + ROMSTAGE(0x120000, 128K) + STACK(0x140000, 0x3ff00) + PRERAM_CBMEM_CONSOLE(0x180000, 8K) + FMAP_CACHE(0x182000, 2K) + CBFS_MCACHE(0x182800, 8K) + RAMSTAGE(0x200000, 16M) +} diff --git a/src/mainboard/raptor-cs/talos-2/romstage.c b/src/mainboard/raptor-cs/talos-2/romstage.c new file mode 100644 index 00000000000..47f77ee9b31 --- /dev/null +++ b/src/mainboard/raptor-cs/talos-2/romstage.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void main(void) +{ + console_init(); + istep_8_9(); + istep_8_10(); + run_ramstage(); +} diff --git a/src/soc/ibm/Kconfig b/src/soc/ibm/Kconfig new file mode 100644 index 00000000000..40a09dc19f0 --- /dev/null +++ b/src/soc/ibm/Kconfig @@ -0,0 +1 @@ +source "src/soc/ibm/*/Kconfig" diff --git a/src/soc/ibm/power9/Kconfig b/src/soc/ibm/power9/Kconfig new file mode 100644 index 00000000000..756ac70537d --- /dev/null +++ b/src/soc/ibm/power9/Kconfig @@ -0,0 +1,9 @@ +config SOC_IBM_POWER9 + bool + help + This SoC is the minimal template working on POWER9 + Talos II platform. + +if SOC_IBM_POWER9 + # nothing here yet +endif diff --git a/src/soc/ibm/power9/Makefile.inc b/src/soc/ibm/power9/Makefile.inc new file mode 100644 index 00000000000..f0d092b103c --- /dev/null +++ b/src/soc/ibm/power9/Makefile.inc @@ -0,0 +1,34 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ifeq ($(CONFIG_CPU_IBM_POWER9),y) + +bootblock-y += bootblock.c +bootblock-y += rom_media.c +romstage-y += rom_media.c +romstage-y += romstage.c +romstage-y += vpd.c +romstage-y += istep_8_9.c +romstage-y += istep_8_10.c +romstage-y += istep_13_2.c +romstage-y += istep_13_3.c +romstage-y += istep_13_4.c +romstage-y += istep_13_6.c +romstage-y += istep_13_8.c +romstage-y += istep_13_9.c +romstage-y += istep_13_10.c +romstage-y += istep_13_11.c +romstage-y += istep_13_13.c +romstage-y += istep_14_1.c +romstage-y += istep_14_2.c +romstage-y += istep_14_3.c +romstage-y += istep_14_5.c +romstage-y += i2c.c +romstage-y += ccs.c +romstage-y += timer.c +ramstage-y += chip.c +ramstage-y += rom_media.c +ramstage-y += timer.c +ramstage-y += istep_18_11.c +ramstage-y += istep_18_12.c + +endif diff --git a/src/soc/ibm/power9/bootblock.c b/src/soc/ibm/power9/bootblock.c new file mode 100644 index 00000000000..bb4a9480a1f --- /dev/null +++ b/src/soc/ibm/power9/bootblock.c @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +void bootblock_soc_early_init(void); + +void bootblock_soc_early_init(void) +{ +} diff --git a/src/soc/ibm/power9/chip.c b/src/soc/ibm/power9/chip.c new file mode 100644 index 00000000000..98e1d570d89 --- /dev/null +++ b/src/soc/ibm/power9/chip.c @@ -0,0 +1,6 @@ +#include + +struct chip_operations soc_ibm_power9_ops = { + CHIP_NAME("POWER9") +}; + diff --git a/src/soc/ibm/power9/istep_8_10.c b/src/soc/ibm/power9/istep_8_10.c new file mode 100644 index 00000000000..1ae419500f9 --- /dev/null +++ b/src/soc/ibm/power9/istep_8_10.c @@ -0,0 +1,1210 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include + +void istep_8_10(void) +{ + printk(BIOS_EMERG, "starting istep 8.10\n"); + report_istep(8, 10); + p9_io_xbus_scominit(0); + p9_io_xbus_scominit(1); + printk(BIOS_EMERG, "ending istep 8.10\n"); + return; +} + +void p9_io_xbus_scominit(const uint8_t group) +{ + scom_or_for_chiplet(XB_CHIPLET_ID, 0x8009F8000000003F, PPC_BIT(52)); + wait_us(50, false); + scom_or_for_chiplet(XB_CHIPLET_ID, 0x800C9C000000003F, PPC_BIT(48)); + wait_us(50, false); + + if(0 == group) + { + p9_xbus_g0_scom(); + } + else if(1 == group) + { + p9_xbus_g1_scom(); + } + + if(!(read_scom(PB_CENT_SM0_PB_CENT_FIR_REG) & PPC_BIT(13))) + { + write_scom_for_chiplet(XB_CHIPLET_ID, XBUS_FIR_ACTION0_REG, XBUS_PHY_FIR_ACTION0); + write_scom_for_chiplet(XB_CHIPLET_ID, XBUS_FIR_ACTION1_REG, XBUS_PHY_FIR_ACTION1); + write_scom_for_chiplet(XB_CHIPLET_ID, XBUS_FIR_MASK_REG, XBUS_PHY_FIR_MASK); + } +} + +void p9_xbus_g0_scom() +{ + for(uint64_t id = 0; id <= 0x11; ++id) + { + // register P9A_XBUS_0_RX0_RXPACKS[0:3]_SLICE[0:5]_RX_DATA_DAC_SPARE_MODE_PL + // IOF1_RX_RX0_RXPACKS_[0:3]_RXPACK_RD_SLICE_[0:5]_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF + // IOF1_RX_RX0_RXPACKS_[0:3]_RXPACK_RD_SLICE_[0:5]_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF + // IOF1_RX_RX0_RXPACKS_[0:3]_RXPACK_RD_SLICE_[0:5]_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8000000006010C3F | id << 32, + ~PPC_BITMASK(53, 55)); + } + + for(uint64_t id = 0; id <= 0x10; ++id) + { + // P9A_XBUS_0_RX0_RXPACKS[0:3]_SLICE[0:5]_RX_DAC_CNTL1_EO_PL + // IOF1_RX_RX0_RXPACKS_[0:3]_RXPACK_RD_SLICE_[0:5]_RX_DAC_REGS_RX_DAC_REGS_RX_LANE_ANA_PDWN_OFF + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8000080006010C3F | id << 32, + ~PPC_BIT(54)); + } + // register P9A_XBUS_0_RX0_RXPACKS2_SLICE1_RX_DAC_CNTL1_EO_PL + // IOF1_RX_RX0_RXPACKS_2_RXPACK_RD_SLICE_1_RX_DAC_REGS_RX_DAC_REGS_RX_LANE_ANA_PDWN_ON + scom_or_for_chiplet(XB_CHIPLET_ID, 0x8000081106010C3F, PPC_BIT(54)); + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8000080006010C3F | 0x11ull << 32, + PPC_BIT(54)); + + for(uint64_t id = 0; id <= 0x11; ++id) + { + // register P9A_XBUS_0_RX0_RXPACKS[0:3]_SLICE[0:5]_RX_DAC_CNTL5_EO_PL + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8000280006010C3F | id << 32, + ~PPC_BITMASK(44, 56)); + } + + for(uint64_t id = 0; id <= 0x11; ++id) + { + // register P9A_XBUS_0_RX0_RXPACKS[0:3]_SLICE[0:5]_RX_DAC_CNTL6_EO_PL + scom_and_or_for_chiplet(XB_CHIPLET_ID, + 0x8000300006010C3F | id << 32, + ~PPC_BITMASK(52, 60), + PPC_BITMASK(49, 50) | PPC_BITMASK(54, 56)); + } + + for(uint64_t id = 0; id <= 0x11; ++id) + { + // register P9A_XBUS_0_RX0_RXPACKS[0:3]_SLICE[0:5]_RX_DAC_CNTL9_E_PL + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8000C00006010C3F | id << 32, + ~PPC_BITMASK(48, 60)); + } + + for(uint64_t id = 0; id <= 0x11; ++id) + { + // register P9A_XBUS_0_RX0_RXPACKS[0:3]_SLICE[0:5]_RX_BIT_MODE1_EO_PL + // IOF1_RX_RX0_RXPACKS_[0:3]_RXPACK_RD_SLICE_[0:5]_RD_RX_BIT_REGS_RX_LANE_DIG_PDWN_OFF + scom_and_for_chiplet(XB_CHIPLET_ID, + 0x8002200006010C3F | id << 32, + ~PPC_BIT(48)); + } + + // register P9A_XBUS_0_RX0_RXPACKS3_SLICE4_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_3_RXPACK_RD_SLICE_4_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_A_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00006010C3F, + ~PPC_BITMASK(48, 63), + PPC_BIT(51)); + // register P9A_XBUS_0_RX0_RXPACKS3_SLICE5_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_3_RXPACK_RD_SLICE_5_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_B_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00106010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(48, 51) | PPC_BITMASK(58, 62)); + // register P9A_XBUS_0_RX0_RXPACKS3_SLICE1_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_3_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_C_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00206010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(53, 56) | PPC_BITMASK(58, 61)); + // register P9A_XBUS_0_RX0_RXPACKS3_SLICE3_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_3_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_D_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00306010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(57, 61) | PPC_BITMASK(61, 63) ); + // register P9A_XBUS_0_RX0_RXPACKS3_SLICE0_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_3_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_E_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00406010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(54, 58) | PPC_BITMASK(60, 63)); + // register P9A_XBUS_0_RX0_RXPACKS3_SLICE2_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_3_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_F_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00506010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(55, 59) | PPC_BITMASK(60, 63)); + // register P9A_XBUS_0_RX0_RXPACKS2_SLICE2_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_2_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_G_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00606010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(51, 52)); + // register P9A_XBUS_0_RX0_RXPACKS2_SLICE0_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_2_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_H_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00706010C3F, + ~PPC_BITMASK(48, 63), + PPC_BIT(48) | PPC_BITMASK(51, 53)); + // register P9A_XBUS_0_RX0_RXPACKS2_SLICE3_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_2_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_A_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00806010C3F, + ~PPC_BITMASK(48, 63), + PPC_BIT(51)); + // register P9A_XBUS_0_RX0_RXPACKS1_SLICE1_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_H_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00906010C3F, + ~PPC_BITMASK(48, 63), + PPC_BIT(48) | PPC_BITMASK(51, 53)); + // register P9A_XBUS_0_RX0_RXPACKS1_SLICE3_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_1_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_G_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00A06010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(51, 52)); + // register P9A_XBUS_0_RX0_RXPACKS1_SLICE0_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_F_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00B06010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(55, 59) | PPC_BITMASK(60, 63)); + // register P9A_XBUS_0_RX0_RXPACKS1_SLICE2_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_1_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_E_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00C06010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(54, 58) | PPC_BITMASK(60, 63)); + // register P9A_XBUS_0_RX0_RXPACKS0_SLICE0_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_D_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00D06010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(57, 61) | PPC_BITMASK(61, 63) ); + // register P9A_XBUS_0_RX0_RXPACKS0_SLICE2_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_C_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00E06010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(53, 56) | PPC_BITMASK(58, 61)); + // register P9A_XBUS_0_RX0_RXPACKS0_SLICE1_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_B_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C00F06010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(48, 51) | PPC_BITMASK(58, 62)); + // register P9A_XBUS_0_RX0_RXPACKS0_SLICE3_RX_BIT_MODE1_E_PL + // IOF1_RX_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_A_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C01006010C3F, + ~PPC_BITMASK(48, 63), + PPC_BIT(51)); + + + // register P9A_XBUS_0_RX0_RXPACKS3_SLICE4_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_3_RXPACK_RD_SLICE_4_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_A_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80006010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(49) | PPC_BIT(52)); + // register P9A_XBUS_0_RX0_RXPACKS3_SLICE5_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_3_RXPACK_RD_SLICE_5_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_B_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80106010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(50, 54)); + // register P9A_XBUS_0_RX0_RXPACKS3_SLICE1_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_3_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_C_12_ACGH_16_22 + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80206010C3F, + ~PPC_BITMASK(48, 54)); + // register P9A_XBUS_0_RX0_RXPACKS3_SLICE3_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_3_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_D_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80306010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(49, 50)); + // register P9A_XBUS_0_RX0_RXPACKS3_SLICE0_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_3_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_EF_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80406010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(49)); + // register P9A_XBUS_0_RX0_RXPACKS3_SLICE2_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_3_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_EF_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80506010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(49)); + // register P9A_XBUS_0_RX0_RXPACKS2_SLICE2_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_2_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_GH_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80606010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(54, 55)); + // register P9A_XBUS_0_RX0_RXPACKS2_SLICE0_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_2_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_GH_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80706010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(54, 55)); + // register P9A_XBUS_0_RX0_RXPACKS2_SLICE3_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_2_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_A_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80806010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(49) | PPC_BIT(52)); + // register P9A_XBUS_0_RX0_RXPACKS1_SLICE1_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_1_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_GH_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80906010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(54, 55)); + // register P9A_XBUS_0_RX0_RXPACKS1_SLICE3_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_1_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_GH_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80A06010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(54, 55)); + // register P9A_XBUS_0_RX0_RXPACKS1_SLICE0_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_1_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_EF_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80B06010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(49)); + // register P9A_XBUS_0_RX0_RXPACKS1_SLICE2_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_1_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_EF_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80C06010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(49)); + // register P9A_XBUS_0_RX0_RXPACKS0_SLICE0_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_0_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_D_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80D06010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(49, 50)); + // register P9A_XBUS_0_RX0_RXPACKS0_SLICE2_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_0_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_C_12_ACGH_16_22 + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80E06010C3F, + ~PPC_BITMASK(48, 54)); + // register P9A_XBUS_0_RX0_RXPACKS0_SLICE1_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_0_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_B_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C80F06010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(50, 54)); + // register P9A_XBUS_0_RX0_RXPACKS0_SLICE3_RX_BIT_MODE2_E_PL + // IOF1_RX_RX0_RXPACKS_0_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_A_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8002C81006010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(49) | PPC_BIT(52)); + + + for(uint64_t id = 0; id <= 0x11; ++id) + { + // register P9A_XBUS_0_TX0_TXPACKS[0:3]_SLICE[0:4]_TX_MODE1_PL + // IOF1_TX_WRAP_TX0_TXPACKS_[0:3]_TXPACK_DD_SLICE_[0:4]_DD_TX_BIT_REGS_TX_LANE_PDWN_ENABLED + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8004040006010C3F | id << 32, + ~PPC_BIT(48)); + } + + for(uint64_t id = 0; id <= 0x10; ++id) + { + // register P9A_XBUS_0_TX0_TXPACKS[0:3]_SLICE[0:4]_TX_MODE2_PL + // IOF1_TX_WRAP_TX0_TXPACKS_[0:3]_TXPACK_DD_SLICE_[0:4]_DD_TX_BIT_REGS_TX_CAL_LANE_SEL_ON + scom_or_for_chiplet( + XB_CHIPLET_ID, + 0x80040C0006010C3F | id << 32, + PPC_BIT(62)); + } + + // register P9A_XBUS_0_TX0_TXPACKS0_SLICE0_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_0_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_AB_HALF_A_0_15 + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0006010C3F, + ~PPC_BITMASK(48, 63)); + // register P9A_XBUS_0_TX0_TXPACKS0_SLICE1_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_0_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_AB_HALF_A_0_15 + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0106010C3F, + ~PPC_BITMASK(48, 63)); + // register P9A_XBUS_0_TX0_TXPACKS0_SLICE2_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_0_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_C_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0206010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(59, 62)); + // register P9A_XBUS_0_TX0_TXPACKS0_SLICE3_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_0_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_D_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0306010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(59, 63)); + // register P9A_XBUS_0_TX0_TXPACKS1_SLICE0_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_1_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_E_HALF_B_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0406010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(60, 63)); + // register P9A_XBUS_0_TX0_TXPACKS1_SLICE1_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_1_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_F_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0506010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(57, 61)); + // register P9A_XBUS_0_TX0_TXPACKS1_SLICE2_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_1_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_G_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0606010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(52, 53) | PPC_BITMASK(57, 58) | PPC_BITMASK(62, 63)); + // register P9A_XBUS_0_TX0_TXPACKS1_SLICE3_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_1_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_H_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0706010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(52, 54) | PPC_BITMASK(57, 59) | PPC_BITMASK(62, 63)); + // register P9A_XBUS_0_TX0_TXPACKS2_SLICE0_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_2_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_AB_HALF_A_0_15 + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0806010C3F, + ~PPC_BITMASK(48, 63)); + // register P9A_XBUS_0_TX0_TXPACKS2_SLICE1_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_2_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_H_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0906010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(52, 54) | PPC_BITMASK(57, 59) | PPC_BITMASK(62, 63)); + // register P9A_XBUS_0_TX0_TXPACKS2_SLICE2_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_2_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_G_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0A06010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(52, 53) | PPC_BITMASK(57, 58) | PPC_BITMASK(62, 63)); + // register P9A_XBUS_0_TX0_TXPACKS2_SLICE3_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_2_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_F_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0B06010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(57, 61)); + // register P9A_XBUS_0_TX0_TXPACKS3_SLICE0_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_3_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_E_HALF_B_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0C06010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(60, 63)); + // register P9A_XBUS_0_TX0_TXPACKS3_SLICE1_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_3_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_D_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0D06010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(59, 63)); + // register P9A_XBUS_0_TX0_TXPACKS3_SLICE2_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_3_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_C_0_15 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0E06010C3F, + ~PPC_BITMASK(48, 63), + PPC_BITMASK(59, 62)); + // register P9A_XBUS_0_TX0_TXPACKS3_SLICE3_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_3_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_AB_HALF_A_0_15 + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x80043C0F06010C3F, + ~PPC_BITMASK(48, 63)); + // register P9A_XBUS_0_TX0_TXPACKS3_SLICE4_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_3_TXPACK_DD_SLICE_4_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_AB_HALF_A_0_15 + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x80043C1006010C3F, + ~PPC_BITMASK(48, 63)); + + + // register P9A_XBUS_0_TX0_TXPACKS0_SLICE0_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_0_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_A_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440006010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(48)); + // register P9A_XBUS_0_TX0_TXPACKS0_SLICE1_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_0_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_B_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440106010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(48, 52)); + // register P9A_XBUS_0_TX0_TXPACKS0_SLICE2_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_0_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_C_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440206010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(48, 51) | PPC_BITMASK(53, 54)); + // register P9A_XBUS_0_TX0_TXPACKS0_SLICE3_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_0_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_DG_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440306010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(51, 52)); + // register P9A_XBUS_0_TX0_TXPACKS1_SLICE0_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_1_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_E_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440406010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(48) | PPC_BITMASK(50, 53)); + // register P9A_XBUS_0_TX0_TXPACKS1_SLICE1_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_1_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_F_HALF_A_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440506010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(50)); + // register P9A_XBUS_0_TX0_TXPACKS1_SLICE2_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_1_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_DG_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440606010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(51, 52)); + // register P9A_XBUS_0_TX0_TXPACKS1_SLICE3_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_1_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_H_HALF_B_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440706010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(48) | PPC_BITMASK(50, 53)); + // register P9A_XBUS_0_TX0_TXPACKS2_SLICE0_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_2_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_A_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440806010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(48)); + // register P9A_XBUS_0_TX0_TXPACKS2_SLICE1_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_2_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_H_HALF_B_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440906010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(48) | PPC_BITMASK(51, 53)); + // register P9A_XBUS_0_TX0_TXPACKS2_SLICE2_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_2_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_DG_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440A06010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(51, 52)); + // register P9A_XBUS_0_TX0_TXPACKS2_SLICE3_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_2_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_F_HALF_A_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440B06010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(48) | PPC_BITMASK(50, 53)); + // register P9A_XBUS_0_TX0_TXPACKS3_SLICE0_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_3_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_E_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440C06010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(48) | PPC_BITMASK(50, 53)); + // register P9A_XBUS_0_TX0_TXPACKS3_SLICE1_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_3_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_DG_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440D06010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(51, 52)); + // register P9A_XBUS_0_TX0_TXPACKS3_SLICE2_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_3_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_C_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440E06010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(48) | PPC_BITMASK(50, 53)); + // register P9A_XBUS_0_TX0_TXPACKS3_SLICE3_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_3_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_B_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004440F06010C3F, + ~PPC_BITMASK(48, 54), + PPC_BITMASK(48, 52)); + // register P9A_XBUS_0_TX0_TXPACKS3_SLICE4_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX0_TXPACKS_3_TXPACK_DD_SLICE_4_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_A_16_22 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8004441006010C3F, + ~PPC_BITMASK(48, 54), + PPC_BIT(48)); + + + // register P9A_XBUS_0_RX0_RX_SPARE_MODE_PG + // IOF1_RX_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PG_SPARE_MODE_1_ON + scom_or_for_chiplet( + XB_CHIPLET_ID, + 0x8008000006010C3F, + PPC_BIT(49)); + // register P9A_XBUS_0_RX0_RX_ID1_PG + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8008080006010C3F, + ~PPC_BITMASK(48, 53)); + // register P9A_XBUS_0_RX0_RX_CTL_MODE1_EO_PG + // IOF1_RX_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_CLKDIST_PDWN_OFF + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8008100006010C3F, + ~PPC_BIT(48)); + // register P9A_XBUS_0_RX0_RX_CTL_MODE5_EO_PG + // IOF1_RX_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DYN_RECAL_INTERVAL_TIMEOUT_SEL_TAP5 + // IOF1_RX_RX0_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DYN_RECAL_STATUS_RPT_TIMEOUT_SEL_TAP1 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8008300006010C3F, + ~PPC_BITMASK(51, 55), + PPC_BIT(51) | PPC_BIT(53) | PPC_BIT(55)); + // register P9A_XBUS_0_RX0_RX_CTL_MODE7_EO_PG + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8008400006010C3F, + ~PPC_BITMASK(60, 63), + PPC_BIT(62) | PPC_BIT(60)); + // register P9A_XBUS_0_RX0_RX_CTL_MODE23_EO_PG + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8008C00006010C3F, + ~PPC_BITMASK(55, 60), + PPC_BIT(51) | PPC_BITMASK(56, 60)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE23_EO_PG + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PEAK_TUNE_OFF + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_LTE_EN_OFF + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DFEHISPD_EN_ON + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DFE12_EN_ON + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8008D00006010C3F, + ~PPC_BITMASK(48, 63), + PPC_BIT(51) | PPC_BIT(57) | PPC_BIT(61)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE29_EO_PG + scom_or_for_chiplet( + XB_CHIPLET_ID, + 0x8009700006010C3F, + PPC_BIT(48)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE27_EO_PG + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RC_ENABLE_CTLE_1ST_LATCH_OFFSET_CAL_ON + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8009800006010C3F, + ~(PPC_BITMASK(49, 55) | PPC_BITMASK(57, 63)), + PPC_BIT(59)); + // P9A_XBUS_0_RX1_RX_ID2_PG + scom_or_for_chiplet( + XB_CHIPLET_ID, + 0x8009900006010C3F, + PPC_BITMASK(57, 58)); + // P9A_XBUS_0_RX1_RX_CTL_MODE1_E_PG + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_MASTER_MODE_MASTER + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PDWN_LITE_DISABLE_ON + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_FENCE_FENCED + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8009980006010C3F, + ~PPC_BITMASK(48, 52), + PPC_BIT(52)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE2_E_PG + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8009A00006010C3F, + ~PPC_BITMASK(48, 51), + PPC_BIT(48) | PPC_BITMASK(50, 51)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE3_E_PG + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8009B00006010C3F, + ~PPC_BITMASK(48, 51), + PPC_BIT(51)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE5_E_PG + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8009B80006010C3F, + ~PPC_BITMASK(44, 56), + PPC_BIT(50) | PPC_BIT(54) | PPC_BIT(57) | PPC_BIT(61)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE6_E_PG + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8009C80006010C3F, + ~(PPC_BITMASK(48, 58) | PPC_BITMASK(61, 63)), + PPC_BITMASK(51, 54) | PPC_BIT(56) | PPC_BIT(58) | PPC_BIT(61) | PPC_BIT(63)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE8_E_PG + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DYN_RPR_ERR_CNTR1_DURATION_TAP5 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8009D00006010C3F, + ~PPC_BITMASK(48, 58), + PPC_BITMASK(50, 56) | PPC_BIT(58)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE9_E_PG + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DYN_RPR_ERR_CNTR2_DURATION_TAP5 + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8009E00006010C3F, + ~PPC_BITMASK(48, 55)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE12_E_PG + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8009E80006010C3F, + ~PPC_BITMASK(48, 55), + PPC_BITMASK(49, 55)); + // register P9A_XBUS_0_RX1_RX_GLBSM_SPARE_MODE_PG + // IOF1_RX_RX1_RXCTL_GLBSM_REGS_RX_DESKEW_BUMP_AFTER_AFTER + // IOF1_RX_RX1_RXCTL_GLBSM_REGS_RX_PG_GLBSM_SPARE_MODE_2_ON + scom_or_for_chiplet( + XB_CHIPLET_ID, + 0x800A800006010C3F, + PPC_BIT(11) | PPC_BIT(35)); + // register P9A_XBUS_0_RX1_RX_GLBSM_CNTL3_EO_PG + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x800AE80006010C3F, + ~PPC_BITMASK(56, 57), + PPC_BIT(58)); + // register P9A_XBUS_0_RX1_RX_GLBSM_MODE1_EO_PG + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x800AF80006010C3F, + ~PPC_BITMASK(48, 55), + PPC_BITMASK(48, 49) | PPC_BITMASK(52, 53)); + // register P9A_XBUS_0_RX1_RX_DATASM_SPARE_MODE_PG + // IOF1_RX_RX1_RXCTL_DATASM_DATASM_REGS_RX_CTL_DATASM_CLKDIST_PDWN_OFF + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x800B800006010C3F, + ~PPC_BIT(60)); + // register P9A_XBUS_0_TX1_TX_SPARE_MODE_PG + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x800C040006010C3F, + ~PPC_BITMASK(56, 57)); + // register P9A_XBUS_0_TX1_TX_ID1_PG + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x800C0C0006010C3F, + ~PPC_BITMASK(48, 53)); + // register P9A_XBUS_0_TX1_TX_CTL_MODE1_EO_PG + // IOF1_TX_WRAP_TX1_TXCTL_CTL_REGS_TX_CTL_REGS_TX_CLKDIST_PDWN_OFF + // IOF1_TX_WRAP_TX1_TXCTL_CTL_REGS_TX_CTL_REGS_TX_PDWN_LITE_DISABLE_ON + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x800C140006010C3F, + ~(PPC_BITMASK(53, 57) | PPC_BIT(48)), + PPC_BIT(57) | PPC_BIT(59)); + // register P9A_XBUS_0_TX1_TX_CTL_MODE2_EO_PG + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x800C1C0006010C3F, + ~PPC_BITMASK(56, 62), + PPC_BIT(58) | PPC_BIT(62)); + // register P9A_XBUS_0_TX1_TX_CTL_CNTLG1_EO_PG + // IOF1_TX_WRAP_TX1_TXCTL_CTL_REGS_TX_CTL_REGS_TX_DRV_CLK_PATTERN_GCRMSG_DRV_0S + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x800C240006010C3F, + ~PPC_BITMASK(48, 49)); + // register P9A_XBUS_0_TX1_TX_ID2_PG + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x800C840006010C3F, + ~(PPC_BITMASK(49, 55) | PPC_BITMASK(57, 63)), + PPC_BIT(59)); + // register P9A_XBUS_0_TX1_TX_CTL_MODE1_E_PG + // IOF1_TX_WRAP_TX1_TXCTL_CTL_REGS_TX_CTL_REGS_TX_DYN_RECAL_INTERVAL_TIMEOUT_SEL_TAP5 + // IOF1_TX_WRAP_TX1_TXCTL_CTL_REGS_TX_CTL_REGS_TX_DYN_RECAL_STATUS_RPT_TIMEOUT_SEL_TAP1 + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x800C8C0006010C3F, + ~PPC_BITMASK(55, 59), + PPC_BIT(55) | PPC_BIT(57) | PPC_BIT(59)); + // register P9A_XBUS_0_TX1_TX_CTL_MODE2_E_PG + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x800CEC0006010C3F, + ~PPC_BITMASK(48, 55)); + // register P9A_XBUS_0_TX1_TX_CTL_MODE3_E_PG + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x800CF40006010C3F, + ~PPC_BITMASK(48, 55), + PPC_BITMASK(49, 55)); + // register P9A_XBUS_0_TX1_TX_CTLSM_MODE1_EO_PG + // IOF1_TX_WRAP_TX1_TXCTL_TX_CTL_SM_REGS_TX_FFE_BOOST_EN_ON + scom_or_for_chiplet( + XB_CHIPLET_ID, + 0x800D2C0006010C3F, + PPC_BIT(59)); + // register P9A_XBUS_0_TX_IMPCAL_P_4X_PB + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x800F1C0006010C3F, + ~PPC_BITMASK(48, 52), + PPC_BITMASK(49, 51)); +} + +void p9_xbus_g1_scom() +{ + for(uint64_t id = 0; id <= 0x11; ++id) + { + // register P9A_XBUS_0_RX1_RXPACKS[0:3]_SLICE[0:5]_RX_DATA_DAC_SPARE_MODE_PL + // l_IOF1_RX_RX1_RXPACKS_[0:3]_RXPACK_RD_SLICE_[0:5]_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_5_OFF + // l_IOF1_RX_RX1_RXPACKS_[0:3]_RXPACK_RD_SLICE_[0:5]_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_6_OFF + // l_IOF1_RX_RX1_RXPACKS_[0:3]_RXPACK_RD_SLICE_[0:5]_RX_DAC_REGS_RX_DAC_REGS_RX_PL_DATA_DAC_SPARE_MODE_7_OFF + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8000002006010C3F | id << 32, + ~PPC_BITMASK(53, 55)); + } + + for(uint64_t id = 0; id <= 0x10; ++id) + { + // register P9A_XBUS_0_RX1_RXPACKS[0:3]_SLICE[0:5]_RX_DAC_CNTL1_EO_PL + // IOF1_RX_RX1_RXPACKS_[0:3]_RXPACK_RD_SLICE_[0:5]_RX_DAC_REGS_RX_DAC_REGS_RX_LANE_ANA_PDWN_OFF + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8000082006010C3F | id << 32, + ~PPC_BIT(54)); + } + // register P9A_XBUS_0_RX1_RXPACKS2_SLICE3_RX_DAC_CNTL1_EO_PL + // IOF1_RX_RX1_RXPACKS_2_RXPACK_RD_SLICE_3_RX_DAC_REGS_RX_DAC_REGS_RX_LANE_ANA_PDWN_ON + scom_or_for_chiplet( + XB_CHIPLET_ID, + 0x8000083106010C3F | 0x11ull << 32, + PPC_BIT(54)); + + for(uint64_t id = 0; id <= 0x11; ++id) + { + // register P9A_XBUS_0_RX1_RXPACKS[0:3]_SLICE[0:5]_RX_DAC_CNTL5_EO_PL + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8000282006010C3F | id << 32, + ~PPC_BITMASK(44, 56)); + } + + for(uint64_t id = 0; id <= 0x11; ++id) + { + // register P9A_XBUS_0_RX1_RXPACKS[0:3]_SLICE[0:5]_RX_DAC_CNTL6_EO_PL + scom_and_or_for_chiplet( + XB_CHIPLET_ID, + 0x8000302006010C3F | id << 32, + ~PPC_BITMASK(52, 60), PPC_BITMASK(49, 50) | PPC_BITMASK(54, 56)); + } + + for(uint64_t id = 0; id <= 0x11; ++id) + { + // register P9A_XBUS_0_RX1_RXPACKS[0:3]_SLICE[0:5]_RX_DAC_CNTL9_E_PL + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8000C02006010C3F | id << 32, + ~PPC_BITMASK(48, 60)); + } + + for(uint64_t id = 0; id <= 0x10; ++id) + { + // register P9A_XBUS_0_RX1_RXPACKS[0:3]_SLICE[0:5]_RX_BIT_MODE1_EO_PL + // IOF1_RX_RX1_RXPACKS_[0:3]_RXPACK_RD_SLICE_[0:5]_RD_RX_BIT_REGS_RX_LANE_DIG_PDWN_OFF + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8002202006010C3F | id << 32, + ~PPC_BIT(48)); + } + // register P9A_XBUS_0_RX1_RXPACKS2_SLICE3_RX_BIT_MODE1_EO_PL + // IOF1_RX_RX1_RXPACKS_2_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_LANE_DIG_PDWN_ON + scom_or_for_chiplet(XB_CHIPLET_ID, 0x8002202006010C3F | 0x11ull << 32, PPC_BIT(48)); + + + // register P9A_XBUS_0_RX1_RXPACKS0_SLICE2_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_0_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_A_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02006010C3F, ~PPC_BITMASK(48, 63), PPC_BIT(51)); + // register P9A_XBUS_0_RX1_RXPACKS0_SLICE0_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_0_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_B_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02106010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(48, 51) | PPC_BITMASK(58, 62)); + // register P9A_XBUS_0_RX1_RXPACKS0_SLICE3_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_0_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_C_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02206010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(49, 52) | PPC_BITMASK(58, 61)); + // register P9A_XBUS_0_RX1_RXPACKS0_SLICE1_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_0_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_D_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02306010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(53, 57) | PPC_BITMASK(61, 63)); + // register P9A_XBUS_0_RX1_RXPACKS1_SLICE3_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_1_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_E_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02406010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(54, 58) | PPC_BITMASK(60, 63)); + // register P9A_XBUS_0_RX1_RXPACKS1_SLICE1_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_1_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_F_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02506010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(55, 59) | PPC_BITMASK(60, 63)); + // register P9A_XBUS_0_RX1_RXPACKS1_SLICE2_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_1_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_G_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02606010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(51, 52)); + // register P9A_XBUS_0_RX1_RXPACKS1_SLICE0_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_1_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_H_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02706010C3F, ~PPC_BITMASK(48, 63), PPC_BIT(48) | PPC_BITMASK(51, 53)); + // register P9A_XBUS_0_RX1_RXPACKS2_SLICE0_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_2_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_A_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02806010C3F, ~PPC_BITMASK(48, 63), PPC_BIT(51)); + // register P9A_XBUS_0_RX1_RXPACKS2_SLICE2_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_2_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_H_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02906010C3F, ~PPC_BITMASK(48, 63), PPC_BIT(48) | PPC_BITMASK(51, 53)); + // register P9A_XBUS_0_RX1_RXPACKS2_SLICE1_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_2_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_G_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02A06010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(51, 52)); + // register P9A_XBUS_0_RX1_RXPACKS3_SLICE3_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_3_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_F_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02B06010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(55, 59) | PPC_BITMASK(60, 63)); + // register P9A_XBUS_0_RX1_RXPACKS3_SLICE1_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_3_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_E_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02C06010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(54, 58) | PPC_BITMASK(60, 63)); + // register P9A_XBUS_0_RX1_RXPACKS3_SLICE2_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_3_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_D_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02D06010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(53, 57) | PPC_BITMASK(61, 63)); + // register P9A_XBUS_0_RX1_RXPACKS3_SLICE0_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_3_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_C_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02E06010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(49, 52) | PPC_BITMASK(58, 61)); + // IOF1_RX_RX1_RXPACKS_3_RXPACK_RD_SLICE_4_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_B_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C02F06010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(48, 51) | PPC_BITMASK(58, 62)); + // register P9A_XBUS_0_RX1_RXPACKS3_SLICE4_RX_BIT_MODE1_E_PL + // IOF1_RX_RX1_RXPACKS_3_RXPACK_RD_SLICE_5_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_0_15_PATTERN_24_A_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C03006010C3F, ~PPC_BITMASK(48, 63), PPC_BIT(51)); + + + // register P9A_XBUS_0_RX1_RXPACKS0_SLICE2_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_0_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_A_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82006010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(49) | PPC_BIT(52)); + // register P9A_XBUS_0_RX1_RXPACKS0_SLICE0_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_0_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_B_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82106010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(50, 54)); + // register P9A_XBUS_0_RX1_RXPACKS0_SLICE3_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_0_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_C_12_ACGH_16_22 + scom_and_for_chiplet(XB_CHIPLET_ID, 0x8002C82206010C3F, ~PPC_BITMASK(48, 54)); + // register P9A_XBUS_0_RX1_RXPACKS0_SLICE1_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_0_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_D_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82306010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(49, 50)); + // register P9A_XBUS_0_RX1_RXPACKS1_SLICE3_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_1_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_EF_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82406010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(49)); + // register P9A_XBUS_0_RX1_RXPACKS1_SLICE1_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_1_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_EF_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82506010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(49)); + // register P9A_XBUS_0_RX1_RXPACKS1_SLICE2_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_1_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_GH_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82606010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(54, 55)); + // register P9A_XBUS_0_RX1_RXPACKS1_SLICE0_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_1_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_GH_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82706010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(54, 55)); + // register P9A_XBUS_0_RX1_RXPACKS2_SLICE0_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_2_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_A_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82806010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(49) | PPC_BIT(52)); + // register P9A_XBUS_0_RX1_RXPACKS2_SLICE2_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_2_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_GH_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82906010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(54, 55)); + // register P9A_XBUS_0_RX1_RXPACKS2_SLICE1_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_2_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_GH_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82A06010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(54, 55)); + // register P9A_XBUS_0_RX1_RXPACKS3_SLICE3_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_3_RXPACK_RD_SLICE_3_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_EF_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82B06010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(49)); + // register P9A_XBUS_0_RX1_RXPACKS3_SLICE1_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_3_RXPACK_RD_SLICE_1_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_EF_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82C06010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(49)); + // register P9A_XBUS_0_RX1_RXPACKS3_SLICE2_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_3_RXPACK_RD_SLICE_2_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_D_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82D06010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(49, 50)); + // register P9A_XBUS_0_RX1_RXPACKS3_SLICE0_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_3_RXPACK_RD_SLICE_0_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_C_12_ACGH_16_22 + scom_and_for_chiplet(XB_CHIPLET_ID, 0x8002C82E06010C3F, ~PPC_BITMASK(48, 54)); + // register P9A_XBUS_0_RX1_RXPACKS3_SLICE4_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_3_RXPACK_RD_SLICE_4_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_B_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C82F06010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(50, 54)); + // register P9A_XBUS_0_RX1_RXPACKS3_SLICE5_RX_BIT_MODE2_E_PL + // IOF1_RX_RX1_RXPACKS_3_RXPACK_RD_SLICE_5_RD_RX_BIT_REGS_RX_PRBS_SEED_VALUE_16_22_PATTERN_24_A_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8002C83006010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(49) | PPC_BIT(52)); + + + for(uint64_t id = 0; id <= 0x10; ++id) + { + // register P9A_XBUS_0_TX1_TXPACKS[0:3]_SLICE[0:4]_TX_MODE1_PL + // IOF1_TX_WRAP_TX1_TXPACKS_[0:3]_TXPACK_DD_SLICE_[0:4]_DD_TX_BIT_REGS_TX_LANE_PDWN_ENABLED + scom_and_for_chiplet( + XB_CHIPLET_ID, + 0x8004042006010C3F | id << 32, + ~PPC_BIT(48)); + } + + for(uint64_t id = 0; id <= 0x10; ++id) + { + // register P9A_XBUS_0_TX1_TXPACKS[0:3]_SLICE[0:4]_TX_MODE2_PL + // IOF1_TX_WRAP_TX1_TXPACKS_[0:3]_TXPACK_DD_SLICE_[0:4]_DD_TX_BIT_REGS_TX_CAL_LANE_SEL_ON + scom_or_for_chiplet( + XB_CHIPLET_ID, + 0x80040C2006010C3F | id << 32, + PPC_BIT(62)); + } + + // register P9A_XBUS_0_TX1_TXPACKS0_SLICE0_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_0_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_AB_HALF_A_0_15 + scom_and_for_chiplet(XB_CHIPLET_ID, 0x80043C2006010C3F, ~PPC_BITMASK(48, 63)); + // register P9A_XBUS_0_TX1_TXPACKS0_SLICE1_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_0_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_AB_HALF_A_0_15 + scom_and_for_chiplet(XB_CHIPLET_ID, 0x80043C2106010C3F, ~PPC_BITMASK(48, 63)); + // register P9A_XBUS_0_TX1_TXPACKS0_SLICE2_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_0_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_C_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x80043C2206010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(59, 62)); + // register P9A_XBUS_0_TX1_TXPACKS0_SLICE3_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_0_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_D_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x80043C2306010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(59, 63)); + // register P9A_XBUS_0_TX1_TXPACKS1_SLICE0_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_1_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_E_HALF_B_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x80043C2406010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(60, 63)); + // register P9A_XBUS_0_TX1_TXPACKS1_SLICE1_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_1_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_F_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x80043C2506010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(57, 61)); + // register P9A_XBUS_0_TX1_TXPACKS1_SLICE2_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_1_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_G_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x80043C2606010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(52, 53) | PPC_BITMASK(57, 58) | PPC_BITMASK(62, 63)); + // register P9A_XBUS_0_TX1_TXPACKS1_SLICE3_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_1_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_H_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x80043C2706010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(52, 54) | PPC_BITMASK(57, 59) | PPC_BITMASK(62, 63)); + // register P9A_XBUS_0_TX1_TXPACKS2_SLICE0_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_2_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_AB_HALF_A_0_15 + scom_and_for_chiplet(XB_CHIPLET_ID, 0x80043C2806010C3F, ~PPC_BITMASK(48, 63)); + // register P9A_XBUS_0_TX1_TXPACKS2_SLICE1_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_2_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_H_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x80043C2906010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(52, 54) | PPC_BITMASK(57, 59) | PPC_BITMASK(62, 63)); + // register P9A_XBUS_0_TX1_TXPACKS2_SLICE2_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_2_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_G_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x80043C2A06010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(52, 53) | PPC_BITMASK(57, 58) | PPC_BITMASK(62, 63)); + // register P9A_XBUS_0_TX1_TXPACKS2_SLICE3_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_2_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_F_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x80043C2B06010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(57, 61)); + // register P9A_XBUS_0_TX1_TXPACKS3_SLICE0_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_3_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_E_HALF_B_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x80043C2C06010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(60, 63)); + // register P9A_XBUS_0_TX1_TXPACKS3_SLICE1_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_3_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_D_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x80043C2D06010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(59, 63)); + // register P9A_XBUS_0_TX1_TXPACKS3_SLICE2_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_3_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_C_0_15 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x80043C2E06010C3F, ~PPC_BITMASK(48, 63), PPC_BITMASK(59, 62)); + // register P9A_XBUS_0_TX1_TXPACKS3_SLICE3_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_3_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_AB_HALF_A_0_15 + scom_and_for_chiplet(XB_CHIPLET_ID, 0x80043C2F06010C3F, ~PPC_BITMASK(48, 63)); + // register P9A_XBUS_0_TX1_TXPACKS3_SLICE4_TX_BIT_MODE1_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_3_TXPACK_DD_SLICE_4_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_0_15_PATTERN_TX_AB_HALF_A_0_15 + scom_and_for_chiplet(XB_CHIPLET_ID, 0x80043C3006010C3F, ~PPC_BITMASK(48, 63)); + + + // register P9A_XBUS_0_TX1_TXPACKS0_SLICE0_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_0_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_A_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442006010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(54)); + // register P9A_XBUS_0_TX1_TXPACKS0_SLICE1_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_0_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_B_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442106010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(48, 52)); + // register P9A_XBUS_0_TX1_TXPACKS0_SLICE2_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_0_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_C_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442206010C3F, ~(PPC_BITMASK(48, 51) | PPC_BITMASK(56, 63)), PPC_BITMASK(48, 51) | PPC_BITMASK(53, 54)); + // register P9A_XBUS_0_TX1_TXPACKS0_SLICE3_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_0_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_DG_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442306010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(51, 52)); + // register P9A_XBUS_0_TX1_TXPACKS1_SLICE0_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_1_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_E_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442406010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(48) | PPC_BITMASK(50, 53)); + // register P9A_XBUS_0_TX1_TXPACKS1_SLICE1_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_1_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_F_HALF_A_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442506010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(42)); + // register P9A_XBUS_0_TX1_TXPACKS1_SLICE2_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_1_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_DG_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442606010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(51, 52)); + // register P9A_XBUS_0_TX1_TXPACKS1_SLICE3_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_1_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_H_HALF_B_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442706010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(48) | PPC_BITMASK(50, 53)); + // register P9A_XBUS_0_TX1_TXPACKS2_SLICE0_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_2_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_A_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442806010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(54)); + // register P9A_XBUS_0_TX1_TXPACKS2_SLICE1_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_2_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_H_HALF_B_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442906010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(48) | PPC_BITMASK(51, 53)); + // register P9A_XBUS_0_TX1_TXPACKS2_SLICE2_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_2_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_DG_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442A06010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(51, 52)); + // register P9A_XBUS_0_TX1_TXPACKS2_SLICE3_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_2_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_F_HALF_A_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442B06010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(48) | PPC_BITMASK(50, 53)); + // register P9A_XBUS_0_TX1_TXPACKS3_SLICE0_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_3_TXPACK_DD_SLICE_0_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_E_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442C06010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(48) | PPC_BITMASK(50, 53)); + // register P9A_XBUS_0_TX1_TXPACKS3_SLICE1_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_3_TXPACK_DD_SLICE_1_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_DG_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442D06010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(51, 52)); + // register P9A_XBUS_0_TX1_TXPACKS3_SLICE2_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_3_TXPACK_DD_SLICE_2_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_C_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442E06010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(48) | PPC_BITMASK(50, 53)); + // register P9A_XBUS_0_TX1_TXPACKS3_SLICE3_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_3_TXPACK_DD_SLICE_3_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_B_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004442F06010C3F, ~PPC_BITMASK(48, 54), PPC_BITMASK(48, 52)); + // register P9A_XBUS_0_TX1_TXPACKS3_SLICE4_TX_BIT_MODE2_E_PL + // IOF1_TX_WRAP_TX1_TXPACKS_3_TXPACK_DD_SLICE_4_DD_TX_BIT_REGS_TX_PRBS_SEED_VALUE_16_22_PATTERN_TX_A_16_22 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8004443006010C3F, ~PPC_BITMASK(48, 54), PPC_BIT(54)); + + + // register P9A_XBUS_0_RX1_RX_SPARE_MODE_PG + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PG_SPARE_MODE_1_ON + scom_or_for_chiplet(XB_CHIPLET_ID, 0x8008002006010C3F, PPC_BIT(49)); + // register P9A_XBUS_0_RX1_RX_ID1_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8008082006010C3F, ~PPC_BITMASK(48, 53), PPC_BIT(53)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE1_EO_PG + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_CLKDIST_PDWN_OFF + scom_and_for_chiplet(XB_CHIPLET_ID, 0x8008102006010C3F, ~PPC_BIT(48)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE5_EO_PG + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DYN_RECAL_INTERVAL_TIMEOUT_SEL_TAP5 + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DYN_RECAL_STATUS_RPT_TIMEOUT_SEL_TAP1 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8008302006010C3F, ~PPC_BITMASK(51, 55), PPC_BIT(51) | PPC_BIT(53) | PPC_BIT(55)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE7_EO_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8008402006010C3F, ~PPC_BITMASK(60, 63), PPC_BIT(62) | PPC_BIT(60)); + // register P9A_XBUS_0_RX0_RX_CTL_MODE23_EO_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8008C00006010C3F, ~PPC_BITMASK(48, 49), PPC_BIT(49)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE23_EO_PG + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PEAK_TUNE_OFF + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_LTE_EN_ON + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DFEHISPD_EN_ON + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DFE12_EN_ON + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8008C02006010C3F, ~PPC_BIT(55), PPC_BITMASK(56, 60)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE29_EO_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8008D02006010C3F, ~PPC_BITMASK(48, 63), PPC_BIT(51) | PPC_BIT(57) | PPC_BIT(61)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE27_EO_PG + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_RC_ENABLE_CTLE_1ST_LATCH_OFFSET_CAL_ON + scom_or_for_chiplet(XB_CHIPLET_ID, 0x8009702006010C3F, PPC_BIT(48)); + // register P9A_XBUS_0_RX1_RX_ID2_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8009802006010C3F, ~(PPC_BITMASK(49, 55) | PPC_BITMASK(57, 63)), PPC_BIT(59)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE1_E_PG + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_PDWN_LITE_DISABLE_ON + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_FENCE_FENCED + scom_or_for_chiplet(XB_CHIPLET_ID, 0x8009902006010C3F, PPC_BITMASK(57, 58)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE2_E_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8009982006010C3F, ~PPC_BITMASK(48, 52), PPC_BIT(52)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE3_E_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8009A02006010C3F, ~PPC_BITMASK(48, 51), PPC_BIT(48) | PPC_BITMASK(50, 51)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE5_E_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8009B02006010C3F, ~PPC_BITMASK(48, 51), PPC_BIT(51)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE6_E_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8009B82006010C3F, ~PPC_BITMASK(44, 56), PPC_BIT(50) | PPC_BIT(54) | PPC_BIT(57) | PPC_BIT(61)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE8_E_PG + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DYN_RPR_ERR_CNTR1_DURATION_TAP5 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8009C82006010C3F, PPC_BITMASK(48, 55) | PPC_BITMASK(61, 63), PPC_BITMASK(51, 54) | PPC_BIT(56) | PPC_BIT(58) | PPC_BIT(61) | PPC_BIT(63)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE9_E_PG + // IOF1_RX_RX1_RXCTL_CTL_REGS_RX_CTL_REGS_RX_DYN_RPR_ERR_CNTR2_DURATION_TAP5 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8009D02006010C3F, ~PPC_BITMASK(53, 63), PPC_BITMASK(54, 59) | PPC_BIT(61) | PPC_BIT(63)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE11_E_PG + scom_and_for_chiplet(XB_CHIPLET_ID, 0x8009E02006010C3F, ~PPC_BITMASK(48, 55)); + // register P9A_XBUS_0_RX1_RX_CTL_MODE12_E_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x8009E82006010C3F, ~PPC_BITMASK(48, 55), PPC_BITMASK(49, 55)); + // register P9A_XBUS_0_RX1_RX_GLBSM_SPARE_MODE_PG + // IOF1_RX_RX1_RXCTL_GLBSM_REGS_RX_DESKEW_BUMP_AFTER_AFTER + // IOF1_RX_RX1_RXCTL_GLBSM_REGS_RX_PG_GLBSM_SPARE_MODE_2_ON + scom_or_for_chiplet(XB_CHIPLET_ID, 0x800A802006010C3F, PPC_BIT(50) | PPC_BIT(56)); + // register P9A_XBUS_0_RX1_RX_GLBSM_CNTL3_EO_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x800AE82006010C3F, ~PPC_BITMASK(56, 57), PPC_BIT(56)); + // register P9A_XBUS_0_RX1_RX_GLBSM_MODE1_EO_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x800AF82006010C3F, ~PPC_BITMASK(48, 55), PPC_BITMASK(48, 49) | PPC_BITMASK(52, 53)); + // register P9A_XBUS_0_RX1_RX_DATASM_SPARE_MODE_PG + // IOF1_RX_RX1_RXCTL_DATASM_DATASM_REGS_RX_CTL_DATASM_CLKDIST_PDWN_OFF + scom_and_for_chiplet(XB_CHIPLET_ID, 0x800B802006010C3F, ~PPC_BIT(60)); + // register P9A_XBUS_0_TX1_TX_SPARE_MODE_PG + scom_and_for_chiplet(XB_CHIPLET_ID, 0x800C042006010C3F, ~PPC_BITMASK(56, 57)); + // register P9A_XBUS_0_TX1_TX_ID1_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x800C0C2006010C3F, ~PPC_BITMASK(48, 53), PPC_BIT(53)); + // register P9A_XBUS_0_TX1_TX_CTL_MODE1_EO_PG + // IOF1_TX_WRAP_TX1_TXCTL_CTL_REGS_TX_CTL_REGS_TX_CLKDIST_PDWN_OFF + // IOF1_TX_WRAP_TX1_TXCTL_CTL_REGS_TX_CTL_REGS_TX_PDWN_LITE_DISABLE_ON + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x800C142006010C3F, ~(PPC_BIT(48) | PPC_BITMASK(53, 57)), PPC_BIT(57) | PPC_BIT(59)); + // register P9A_XBUS_0_TX1_TX_CTL_MODE2_EO_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x800C1C2006010C3F, ~PPC_BITMASK(56, 62), PPC_BITMASK(52, 55) | PPC_BIT(58) | PPC_BIT(62)); + // register P9A_XBUS_0_TX1_TX_CTL_CNTLG1_EO_PG + // IOF1_TX_WRAP_TX1_TXCTL_CTL_REGS_TX_CTL_REGS_TX_DRV_CLK_PATTERN_GCRMSG_DRV_0S + scom_and_for_chiplet(XB_CHIPLET_ID, 0x800C242006010C3F, ~PPC_BITMASK(48, 49)); + // register P9A_XBUS_0_TX1_TX_ID2_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x800C842006010C3F, ~(PPC_BITMASK(49, 55) | PPC_BITMASK(57, 63)), PPC_BIT(59)); + // register P9A_XBUS_0_TX1_TX_CTL_MODE1_E_PG + // IOF1_TX_WRAP_TX1_TXCTL_CTL_REGS_TX_CTL_REGS_TX_DYN_RECAL_INTERVAL_TIMEOUT_SEL_TAP5 + // IOF1_TX_WRAP_TX1_TXCTL_CTL_REGS_TX_CTL_REGS_TX_DYN_RECAL_STATUS_RPT_TIMEOUT_SEL_TAP1 + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x800C8C2006010C3F, ~PPC_BITMASK(55, 59), PPC_BIT(55) | PPC_BIT(57) | PPC_BIT(59)); + // register P9A_XBUS_0_TX1_TX_CTL_MODE2_E_PG + scom_and_for_chiplet(XB_CHIPLET_ID, 0x800CEC2006010C3F, ~PPC_BITMASK(48, 55)); + // register P9A_XBUS_0_TX1_TX_CTL_MODE3_E_PG + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x800CF42006010C3F, ~PPC_BITMASK(48, 55), PPC_BITMASK(49, 55)); + // register P9A_XBUS_0_TX1_TX_CTLSM_MODE1_EO_PG + // IOF1_TX_WRAP_TX1_TXCTL_TX_CTL_SM_REGS_TX_FFE_BOOST_EN_ON + scom_or_for_chiplet(XB_CHIPLET_ID, 0x800D2C2006010C3F, PPC_BIT(59)); + // register P9A_XBUS_0_TX_IMPCAL_P_4X_PB + scom_and_or_for_chiplet(XB_CHIPLET_ID, 0x800F1C0006010C3F, ~PPC_BITMASK(48, 52), PPC_BITMASK(49, 51)); +} diff --git a/src/soc/ibm/power9/istep_8_9.c b/src/soc/ibm/power9/istep_8_9.c new file mode 100644 index 00000000000..18836e6a126 --- /dev/null +++ b/src/soc/ibm/power9/istep_8_9.c @@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void istep_8_9(void) +{ + printk(BIOS_EMERG, "starting istep 8.9\n"); + report_istep(8, 9); + p9_fbc_no_hp_scom(); + p9_fbc_ioe_tl_scom(); + ioe_tl_fir(); + p9_fbc_ioe_dl_scom(); + ioel_fir(); + printk(BIOS_EMERG, "ending istep 8.9\n"); +} + +void p9_fbc_ioe_dl_scom(void) +{ + // PB_ELL_CFG_REG + // [0] CONFIG_LINK_PAIR: When 1, the two links operate as a pair. + // When 0, only one link is used or they are independent. + // [2] CONFIG_CRC_LANE_ID: When 1, use lane IDs from CRC for lane sparing. + // [4] CONFIG_SL_UE_CRC_ERR: When 1, UEs on the SL ECC cause the packet + // to be treated as a CRC error. + // [8:11] CONFIG_UNUSED1: Spare bits. + // [12:15] CONFIG_PACKET_DELAY_LIMIT: This field indicates the number + // of cycles of delay of frame data that are required for the + // packet to be considered delayed or replayed. (0 is 16 cycles.) + // [28:31] CONFIG_AUTO_TDM_ERROR_RATE: This field contains the error rate + // for the auto-entry TDM mode. + scom_or_for_chiplet(XB_CHIPLET_ID, PB_ELL_CFG_REG, PPC_BIT(0) | PPC_BIT(2) | PPC_BIT(4) | PPC_BITMASK(12, 15) | PPC_BITMASK(28, 31)); + // PB_ELL_REPLAY_TRESHOLD_REG + // [0:3] THRESH_REPLAY_TB_SEL: Replay threshold timebase select. + // [4:7] THRESH_REPLAY_TAP_SEL: Replay threshold tap select. + // [8:10] THRESH_REPLAY_ENABLE: Replay threshold error enable. + scom_or_for_chiplet(XB_CHIPLET_ID, PB_ELL_REPLAY_TRESHOLD_REG, PPC_BITMASK(1, 2) | PPC_BITMASK(4, 10)); + // PB_ELL_SL_ECC_TRESHOLD_REG + // [0:3] THRESH_SL_ECC_TB_SEL: SL ECC threshold timebase select. + // [4:7] THRESH_SL_ECC_TAP_SEL: SL ECC threshold tap select. + // [8:9] THRESH_SL_ECC_ENABLE: SL ECC threshold error enable. + // [10:25] THRESH_SL_ECC_UNUSED1: Spare bits. + scom_or_for_chiplet(XB_CHIPLET_ID, PB_ELL_SL_ECC_TRESHOLD_REG, PPC_BITMASK(1, 10)); +} + +void ioe_tl_fir(void) +{ + // PB_IOE_FIR_ACTION0: Processor bus IOE domain action select for corresponding bit in FIR. + // (Action0,Action1) = Action Select. + // (0,0) Checkstop. + // (0,1) Recoverable Error to Service Processor. + // (1,0) Special Attention to Service Processor. + // (1,1) Invalid. + write_scom(PU_PB_IOE_FIR_ACTION0_REG, FBC_IOE_TL_FIR_ACTION0); + // PB_IOE_FIR_ACTION1: Processor bus FIR LSB of action select for corresponding bit in FIR. + // (Action0,Action1) = Action Select. + // (0,0) Checkstop. + // (0,1) Recoverable Error to Service Processor. + // (1,0) Special Attention to Service Processor. + // (1,1) Invalid. + write_scom(PU_PB_IOE_FIR_ACTION1_REG, FBC_IOE_TL_FIR_ACTION1); + // PU_PB_IOE_FIR_MASK_REG: Power Bus PBEN IOX Domain FIR0 Mask Register + // [0:5] FMR[0:5]_TRAINED_MASK fmr[0:5] trained. + // [6:7] RSV[6:7]_MASK rsv[6:7] mask. + // [8] DOB01_UE_MASK: dob01 ue mask. + // [9] DOB01_CE_MASK: dob01 ce mask. + // [10] DOB01_SUE_MASK: dob01 sue mask. + // [11] DOB23_UE_MASK: dob23 ue mask. + // [12] DOB23_CE_MASK: dob23 ce mask. + // [13] DOB23_SUE_MASK: dob23 sue mask. + // [14] DOB45_UE_MASK: dob45 ue mask. + // [15] DOB45_CE_MASK: dob45 ce mask. + // [16] DOB45_SUE_MASK: dob45 sue mask. + // [17:19] RSV17_MASK: rsv[17:19] mask. + // [20:25] FRAMER[0:5]_ATTN_MASK: framer[0:5] attn mask. + // [26:27] RSV[26:27]_MASK: rsv[26:27] mask. + // [28:33] PARSER[0:5]_ATTN_MASK: parser[0:5] attn mask. + // [34:35] RSV[34:35]_MASK: rsv[34:35] mask. + // [36:37] MB[0:1]_SPATTN_MASK: mb[0:1] spattn mask. + // [38:39] MB[10:11]_SPATTN_MASK: mb[10:11] spattn mask. + // [40:41] MB[20:21]_SPATTN_MASK: mb[20:21] spattn mask. + // [42:43] MB[30:31]_SPATTN_MASK: mb[30:31] spattn mask. + // [44:45] MB[40:41]_SPATTN_MASK: mb[40:41] spattn mask. + // [46:47] MB[50:51]_SPATTN_MASK: mb[50:51] spattn mask. + // [48:51] Reserved. + // [52] DOB01_ERR_MASK: data outbound switch internal error mask - links 01. + // [53] DOB23_ERR_MASK: data outbound switch internal error mask - links 23. + // [54] DOB45_ERR_MASK: data outbound switch internal error mask - links 45. + // [55] Reserved. + // [56] DIB01_ERR_MASK: data inbound switch internal error mask - links 01. + // [57] DIB23_ERR_MASK: data inbound switch internal error mask - links 23. + // [58] DIB45_ERR_MASK: data inbound switch internal error mask - links 45. + // [59:61] Reserved. + // [62] FIR_SCOM_ERR_MASK_DUP: FIR SCOM err mask dup. + // [63] FIR_SCOM_ERR_MASK: FIR SCOM err mask. + write_scom(PU_PB_IOE_FIR_MASK_REG, FBC_IOE_TL_FIR_MASK | FBC_IOE_TL_FIR_MASK_X0_NF); +} + +void ioel_fir(void) +{ + // IOEL_FIR_ACTION0: processor bus FIR MSB of action select for corresponding bit in FIR. + // (Action0,Action1) = Action Select. + // (0,0) = Checkstop. + // (0,1) = Recoverable error to service processor. + // (1,0) = Special attention to service processor. + // (1,1) = Invalid. + write_scom_for_chiplet(XB_CHIPLET_ID, XBUS_LL0_IOEL_FIR_ACTION0_REG, FBC_IOE_DL_FIR_ACTION0); + // IOEL_FIR_ACTION1: processor bus FIR LSB of action select for corresponding bit in FIR. + // (Action0,Action1) = Action Select. + // (0,0) = Checkstop. + // (0,1) = Recoverable error to service processor. + // (1,0) = Special attention to service processor. + // (1,1) = Invalid. + write_scom_for_chiplet(XB_CHIPLET_ID, XBUS_LL0_IOEL_FIR_ACTION1_REG, FBC_IOE_DL_FIR_ACTION1); + // XBUS_LL0_IOEL_FIR_MASK_REG: This register provides a bit mask for the ELL FIR Register. + // [0:1] FIR_LINK[0:1]_TRAINED_MASK: Link [0:1] trained mask. + // [2:3] RESERVED. + // [4:5] FIR_LINK[0:1]_REPLAY_THRESHOLD_MASK: Link [0:1] replay threshold mask. + // [6:7] FIR_LINK[0:1]_CRC_ERROR_MASK: Link [0:1] CRC error mask. + // [8:9] FIR_LINK[0:1]_NAK_RECEIVED_MASK: Link [0:1] NAK received mask. + // [10:11] FIR_LINK[0:1]_REPLAY_BUFFER_FULL_MASK: Link [0:1] replay buffer full mask. + // [12:13] FIR_LINK[0:1]_SL_ECC_THRESHOLD_MASK: Link [0:1] SL ECC threshold mask. + // [14:15] FIR_LINK[0:1]_SL_ECC_CORRECTABLE_MASK: Link [0:1] SL ECC correctable mask. + // [16:17] FIR_LINK[0:1]_SL_ECC_UE_MASK: Link [0:1] SL ECC UE mask. + // [18:39] RESERVED. + // [40:41] FIR_LINK[0:1]_TCOMPLETE_BAD_MASK: Link [0:1] complete bad mask. + // [42:43] RESERVED. + // [44:45] FIR_LINK[0:1]_SPARE_DONE_MASK: Link [0:1] spare done mask. + // [46:47] FIR_LINK[0:1]_TOO_MANY_CRC_ERRORS_MASK: Link [0:1] too many CRC errors mask. + // [48:50] RESERVED. + // [51] FIR_PSAVE_INVALID_STATE_MASK: Psave invalid state mask. + // [52:53] FIR_LINK[0:1]_CORRECTABLE_ARRAY_ERROR_MASK: Link [0:1] correctable array error mask. + // [54:55] FIR_LINK[0:1]_UNCORRECTABLE_ARRAY_ERROR_MASK: Link [0:1] uncorrectable array error mask. + // [56:57] FIR_LINK[0:1]_TRAINING_FAILED_MASK: Link [0:1] training failed mask. + // [58:59] FIR_LINK[0:1]_UNRECOVERABLE_ERROR_MASK: Link [0:1] unrecoverable error mask. + // [60:61] FIR_LINK[0:1]_INTERNAL_ERROR_MASK: Link [0:1] internal error mask. + // [62] FIR_SCOM_ERR_DUP_MASK: FIR SCOM error dup mask. + // [63] FIR_SCOM_ERR_MASK: FIR SCOM error mask. + write_scom_for_chiplet(XB_CHIPLET_ID, XBUS_LL0_IOEL_FIR_MASK_REG, FBC_IOE_DL_FIR_MASK); +} + +void p9_fbc_no_hp_scom(void) +{ + // PB_WEST_MODE_CFG_REG: Power Bus west mode configuration register + // [16:22] PB_CFG_SP_HW_MARK: configures the maximum system pumps an IO unit may issue. + // [23:29] PB_CFG_GP_HW_MARK: configures the maximum group pumps this chip may issue. + // [30:35] PB_CFG_LCL_HW_MARK: configures the maximum local pumps this chip may issue. + scom_and_or(PB_WEST_MODE_CFG_REG, ~PPC_BITMASK(16, 35), 0xFAFEA0000000); + // PB_CENT_MODE_CFG_REG: Power Bus PB CENT Mode Register + // [16:22] PB_CFG_SP_HW_MARK: Configures the maximum system pumps an IO unit may issue. + // [23:29] PB_CFG_GP_HW_MARK: Configures the maximum group pumps this chip may issue. + // [30:35] PB_CFG_LCL_HW_MARK: Configures the maximum local pumps this chip may issue. + scom_and_or(PB_CENT_MODE_CFG_REG, ~PPC_BITMASK(16, 35), 0x7EFEA0000000); + // PB_CENT_GP_COMMAND_RATE_DP0_REG: Power Bus PB CENT GP command RATE DP0 Register + // PB_CFG_GP_CMD_RATE_DP0_LVL[0:7]: Configures the command rate for group pump drop priority 0 at level [0:7]. + write_scom(PB_CENT_GP_COMMAND_RATE_DP0_REG, 0); + // PB_CENT_GP_COMMAND_RATE_DP1_REG: Power Bus PB CENT GP command RATE DP1 Register + // PB_CFG_GP_CMD_RATE_DP1_LVL[0:7]: Configures the command rate for group pump drop priority 1 at level [0:7]. + write_scom(PB_CENT_GP_COMMAND_RATE_DP1_REG, 0); + // PB_CENT_RGP_COMMAND_RATE_DP0_REG: Power Bus PB CENT RGP command RATE DP0 Register + // RWX PB_CFG_RNS_CMD_RATE_DP0_LVL[0:7]: Configures the command rate for remote group pump drop priority 0 at level [0:7]. + write_scom(PB_CENT_RGP_COMMAND_RATE_DP0_REG, 0x30406080A0C1218); + // PB_CENT_RGP_COMMAND_RATE_DP1_REG: Power Bus PB CENT RGP command RATE DP1 Register + // PB_CFG_RNS_CMD_RATE_DP1_LVL[0:7]: Configures the command rate for remote group pump drop priority 1 at level [0:7]. + write_scom(PB_CENT_RGP_COMMAND_RATE_DP1_REG, 0x40508080A0C1218); + // PB_CENT_SP_COMMAND_RATE_DP0_REG: Power Bus PB CENT SP command RATE DP0 Register + // PB_CFG_VG_CMD_RATE_DP0_LVL[0:7]: Configures the command rate for system pump drop priority 0 at level [0:7]. + write_scom(PB_CENT_SP_COMMAND_RATE_DP0_REG, 0x30406080A0C1218); + // PB_CENT_SP_COMMAND_RATE_DP1_REG: Power Bus PB CENT SP command RATE DP1 Register + // PB_CFG_VG_CMD_RATE_DP1_LVL[0:7]: Configures the command rate for system pump drop priority 1 at level [0:7]. + write_scom(PB_CENT_SP_COMMAND_RATE_DP1_REG, 0x30406080A0C1218); + // PB_EAST_MODE_CFG_REG: Power Bus PB East Mode Configuration Register + // [0] pb_east_pbixxx_init + // [1:3] spare + // [4] PB_CFG_CHIP_IS_SYSTEM: configures whether there are other POWER9s in the system. + // [5:7] spare + // [8] PB_CFG_HNG_CHK_DISABLE: Hang Check Disable. + // [9] PB_DBG_CLR_MAX_HANG_STAGE: Resets the maximum hang state level (pb_hang_level). + // [10:11] spare 12:15 pb_cfg_east_sw_ab_wait(0:3) + // [12:15] PB_CFG_SW_AB_WAIT: Adds delay to tc_pb_switch_ab input from TPC during hot plug sequence. + scom_and_or(PB_EAST_MODE_CFG_REG, 0xF1FF00000FFFFFFF, 0x7EFE0000000); +} + +void p9_fbc_ioe_tl_scom(void) +{ + // PB_ELE_PB_FRAMER_PARSER_01_CFG_REG Power Bus Electrical Framer/Parser 01 Configuration Register + // [0] FP0_CREDIT_PRIORITY_4_NOT_8: fp0 credit priority 4 not 8. + // [1] FP0_DISABLE_GATHERING: fp0 disable data gathering. + // [2] FP0_DISABLE_CMD_COMPRESSION: fp0 disable command compression. + // [3] FP0_DISABLE_PRSP_COMPRESSION: fp0 disable prsp compression. + // [4:11] FP0_LL_CREDIT_LO_LIMIT: fp0 ll credit low limit - normal frames in flight limit. Set to ROUNDUP(25.5 - (nest freq/elec freq)*10.75)). + // [12:19] FP0_LL_CREDIT_HI_LIMIT: fp0 ll credit high limit - frames in flight limit during stop_cmds/replay. + // [20] FP0_FMR_DISABLE: fp0 framer disable - turn the framer clocks OFF. + // [21] FP0_FMR_SPARE: fp0 framer spare. + // [22:23] FP01_CMD_EXP_TIME: obs/fmr/prs command expiration time = (value * 2) + 9. + // [24] FP0_RUN_AFTER_FRAME_ERROR: fp0 run after frame error. + // [25] FP0_PRS_DISABLE: fp0 parser disable - turn the parser clocks OFF. + // [26:31] FP0_PRS_SPARE: fp0 parser spare. + // [32] FP1_CREDIT_PRIORITY_4_NOT_8: fp1 credit priority 4 not 8. + // [33] FP1_DISABLE_GATHERING: fp1 disable data gathering. + // [34] FP1_DISABLE_CMD_COMPRESSION: fp1 disable command compression. + // [35] FP1_DISABLE_PRSP_COMPRESSION: fp1 disable prsp compression. + // [36:43] FP1_LL_CREDIT_LO_LIMIT: fp1 ll credit low limit - normal frames in flight limit. Set to ROUNDUP(25.5 - (nest freq/elec freq)*10.75)). + // [44:51] FP1_LL_CREDIT_HI_LIMIT: fp1 ll credit high limit - frames in flight limit during stop_cmds/replay. + // [52] FP1_FMR_DISABLE: fp1 framer disable - turn the framer clocks OFF. + // [53:55] FP1_FMR_SPARE: fp1 framer spare. + // [56] FP1_RUN_AFTER_FRAME_ERROR: fp1 run after frame error. + // [57] FP1_PRS_DISABLE: fp1 parser disable - turn the parser clocks OFF. + // [58:63] FP1_PRS_SPARE: fp1 parser spare. + scom_and_or(PB_ELE_PB_FRAMER_PARSER_01_CFG_REG, 0xfff004fffff007bf, 0x2010000020000); + // PB_ELE_PB_DATA_BUFF_01_CFG_REG: Power Bus Electrical Link Data Buffer 01 Configuration Register + // [0] Reserved. + // [1:7] PB_CFG_LINK0_DOB_LIMIT: pb configuration link0 dob limit - total link credits avail. + // [8] Reserved. + // [9:15] PB_CFG_LINK0_DOB_VC0_LIMIT: pb configuration link0 dob vc0 limit - vc0 link credits max. + // [16] Reserved. + // [17:23] PB_CFG_LINK0_DOB_VC1_LIMIT: pb configuration link0 dob vc1 limit - vc1 link credits max. + // [24:28] PB_CFG_LINK01_DIB_VC_LIMIT: pb configuration link01 dib vc limit - limit per VC for data inbound to + // pbien/s (set to 31/16/8 for 1/2/4 channels in use) (both links use same credit pool). + // [29:32] Reserved. + // [33:39] PB_CFG_LINK1_DOB_LIMIT: pb configuration link1 dob limit - total link credits avail. + // [40] Reserved. + // [41:47] PB_CFG_LINK1_DOB_VC0_LIMIT: pb configuration link1 dob vc0 limit - vc0 link credits max. + // [48] Reserved. + // [49:55] PB_CFG_LINK1_DOB_VC1_LIMIT: pb configuration link1 dob vc1 limit - vc1 link credits max. + scom_and_or(PB_ELE_PB_DATA_BUFF_01_CFG_REG, 0x808080FF808080FF, 0x403C3C1F403C3C00); + // PB_ELE_LINK_TRACE_CFG_REG:Power Bus Electrical Link Trace Configuration Register + // [0:3] LINK00_HI_TRACE_CFG: link00 high trace configuration. + // [4:7] LINK00_LO_TRACE_CFG: link00 low trace configuration. + // [8:11] LINK01_HI_TRACE_CFG: link01 high trace configuration. + // [12:15] LINK01_LO_TRACE_CFG: link01 low trace configuration. + scom_and_or(PB_ELE_LINK_TRACE_CFG_REG, 0x00FFFFFFFFFFFF, 0x4141000000000000); + // PB_ELE_PB_FRAMER_PARSER_23_CFG_REG: Power Bus Electrical Framer/Parser 23 Configuration Register + // [20] FP2_FMR_DISABLE: fp2 framer disable - turn the framer clocks OFF. + // [25] FP2_PRS_DISABLE: fp2 parser disable - turn the parser clocks OFF. + // [52] FP3_FMR_DISABLE: fp3 framer disable - turn the framer clocks OFF. + // [57] FP3_PRS_DISABLE: fp3 parser disable - turn the parser clocks OFF. + scom_or(PB_ELE_PB_FRAMER_PARSER_23_CFG_REG, PPC_BIT(20) | PPC_BIT(25) | PPC_BIT(52) | PPC_BIT(57)); + // PB_ELE_PB_FRAMER_PARSER_45_CFG_REG Power Bus Electrical Framer/Parser 45 Configuration Register + // [20] FP4_FMR_DISABLE: fp4 framer disable - turn the framer clocks OFF. + // [25] FP4_PRS_DISABLE: fp4 parser disable - turn the parser clocks OFF. + // [52] FP5_FMR_DISABLE: fp5 framer disable - turn the framer clocks OFF. + // [57] FP5_PRS_DISABLE: fp5 parser disable - turn the parser clocks OFF. + scom_or(PB_ELE_PB_FRAMER_PARSER_45_CFG_REG, PPC_BIT(20) | PPC_BIT(25) | PPC_BIT(52) | PPC_BIT(57)); + // PB_ELE_MISC_CFG_REG: Power Bus Electrical Miscellaneous Configuration Register + // [0] PB_CFG_IOE01_IS_LOGICAL_PAIR: pb configuration ioe01 is logical pair. + // [1] PB_CFG_IOE23_IS_LOGICAL_PAIR: pb configuration ioe23 is logical pair. + // [2] PB_CFG_IOE45_IS_LOGICAL_PAIR: pb configuration ioe45 is logical pair. + scom_and_or(PB_ELE_MISC_CFG_REG, ~PPC_BITMASK(1, 2), PPC_BIT(0)); +} diff --git a/src/soc/ibm/power9/romstage.c b/src/soc/ibm/power9/romstage.c new file mode 100644 index 00000000000..b0e398e9722 --- /dev/null +++ b/src/soc/ibm/power9/romstage.c @@ -0,0 +1,384 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include // hexdump +#include +#include +#include +#include + +mcbist_data_t mem_data; + +static void dump_mca_data(mca_data_t *mca) +{ + printk(BIOS_SPEW, "\tCL = %d\n", mca->cl); + printk(BIOS_SPEW, "\tCCD_L = %d\n", mca->nccd_l); + printk(BIOS_SPEW, "\tWTR_S = %d\n", mca->nwtr_s); + printk(BIOS_SPEW, "\tWTR_L = %d\n", mca->nwtr_l); + printk(BIOS_SPEW, "\tFAW = %d\n", mca->nfaw); + printk(BIOS_SPEW, "\tRCD = %d\n", mca->nrcd); + printk(BIOS_SPEW, "\tRP = %d\n", mca->nrp); + printk(BIOS_SPEW, "\tRAS = %d\n", mca->nras); + printk(BIOS_SPEW, "\tWR = %d\n", mca->nwr); + printk(BIOS_SPEW, "\tRRD_S = %d\n", mca->nrrd_s); + printk(BIOS_SPEW, "\tRRD_L = %d\n", mca->nrrd_l); + printk(BIOS_SPEW, "\tRFC = %d\n", mca->nrfc); + printk(BIOS_SPEW, "\tRFC_DLR = %d\n", mca->nrfc_dlr); + + int i; + for (i = 0; i < 2; i++) { + if (mca->dimm[i].present) { + printk(BIOS_SPEW, "\tDIMM%d: %dRx%d ", i, mca->dimm[i].mranks, + (mca->dimm[i].width + 1) * 4); + + if (mca->dimm[i].log_ranks != mca->dimm[i].mranks) + printk(BIOS_SPEW, "%dH 3DS ", mca->dimm[i].log_ranks / mca->dimm[i].mranks); + + printk(BIOS_SPEW, "%dGB\n", mca->dimm[i].size_gb); + } + else + printk(BIOS_SPEW, "\tDIMM%d: not installed\n", i); + } +} + +/* TODO: add checks for same ranks configuration for both DIMMs under one MCA */ +static inline bool is_proper_dimm(spd_raw_data spd, int slot) +{ + struct dimm_attr_ddr4_st attr; + if (spd == NULL) + return false; + + if (spd_decode_ddr4(&attr, spd) != SPD_STATUS_OK) { + printk(BIOS_ERR, "Malformed SPD for slot %d\n", slot); + return false; + } + + if (attr.dram_type != SPD_MEMORY_TYPE_DDR4_SDRAM || + attr.dimm_type != SPD_DDR4_DIMM_TYPE_RDIMM || + attr.ecc_extension == false) { + printk(BIOS_ERR, "Bad DIMM type in slot %d\n", slot); + return false; + } + + return true; +} + +static void mark_nonfunctional(int mcs, int mca) +{ + mem_data.mcs[mcs].mca[mca].functional = false; + + /* Propagate upwards */ + if (mem_data.mcs[mcs].mca[mca ^ 1].functional == false) { + mem_data.mcs[mcs].functional = false; + if (mem_data.mcs[mcs ^ 1].functional == false) + die("No functional MCS left"); + } +} + +static uint64_t find_min_mtb_ftb(rdimm_data_t *dimm, int mtb_idx, int ftb_idx) +{ + uint64_t val0 = 0, val1 = 0; + + if (dimm[0].present) + val0 = mtb_ftb_to_nck(dimm[0].spd[mtb_idx], (int8_t)dimm[0].spd[ftb_idx]); + if (dimm[1].present) + val1 = mtb_ftb_to_nck(dimm[1].spd[mtb_idx], (int8_t)dimm[1].spd[ftb_idx]); + + return (val0 < val1) ? val1 : val0; +} + +static uint64_t find_min_multi_mtb(rdimm_data_t *dimm, int mtb_l, int mtb_h, uint8_t mask, int shift) +{ + uint64_t val0 = 0, val1 = 0; + + if (dimm[0].present) + val0 = dimm[0].spd[mtb_l] | ((dimm[0].spd[mtb_h] & mask) << shift); + if (dimm[1].present) + val1 = dimm[1].spd[mtb_l] | ((dimm[1].spd[mtb_h] & mask) << shift); + + return (val0 < val1) ? mtb_ftb_to_nck(val1, 0) : mtb_ftb_to_nck(val0, 0); +} + +/* https://review.coreboot.org/c/coreboot/+/52061 */ +/* DIMM SPD addresses */ +#define DIMM0 0x50 +#define DIMM1 0x51 +#define DIMM2 0x52 +#define DIMM3 0x53 +#define DIMM4 0x54 +#define DIMM5 0x55 +#define DIMM6 0x56 +#define DIMM7 0x57 + +/* This is most of step 7 condensed into one function */ +static void prepare_dimm_data(void) +{ + int i, mcs, mca; + int tckmin = 0x06; // Platform limit + + /* + * DIMMs 4-7 are under a different port. This is not the same as bus, but we + * need to pass that information to I2C function. As there is no easier way, + * use MSB of address and mask it out at the receiving side. This will print + * wrong addresses in dump_spd_info(), but that is small price to pay. + */ + struct spd_block blk = { + .addr_map = { DIMM0, DIMM1, DIMM2, DIMM3, + DIMM4 | 0x80, DIMM5 | 0x80, DIMM6 | 0x80, DIMM7 | 0x80}, + }; + + get_spd_smbus(&blk); + dump_spd_info(&blk); + + /* + * We need to find the highest common (for all DIMMs and the platform) + * supported frequency, meaning we need to compare minimum clock cycle times + * and choose the highest value. For the range supported by the platform we + * can check MTB only. + * + * TODO: check if we can have different frequencies across MCSs. + */ + for (i = 0; i < CONFIG_DIMM_MAX; i++) { + if (is_proper_dimm(blk.spd_array[i], i)) { + mcs = i / DIMMS_PER_MCS; + mca = (i % DIMMS_PER_MCS) / MCA_PER_MCS; + int dimm_idx = i % 2; // (i % DIMMS_PER_MCS) % MCA_PER_MCS + + + /* Maximum for 2 DIMMs on one port (channel, MCA) is 2400 MT/s */ + if (tckmin < 0x07 && mem_data.mcs[mcs].mca[mca].functional) + tckmin = 0x07; + + mem_data.mcs[mcs].functional = true; + mem_data.mcs[mcs].mca[mca].functional = true; + + rdimm_data_t *dimm = &mem_data.mcs[mcs].mca[mca].dimm[dimm_idx]; + + dimm->present = true; + dimm->spd = blk.spd_array[i]; + /* RCD address is the same as SPD, with one additional bit set */ + dimm->rcd_i2c_addr = blk.addr_map[i] | 0x08; + /* + * SPD fields in spd.h are not compatible with DDR4 and those in + * spd_bin.h are just a few of all required. + * + * TODO: add fields that are lacking to either of those files or + * add a file specific to DDR4 SPD. + */ + dimm->width = blk.spd_array[i][12] & 7; + dimm->mranks = ((blk.spd_array[i][12] >> 3) & 0x7) + 1; + dimm->log_ranks = dimm->mranks * (((blk.spd_array[i][6] >> 4) & 0x7) + 1); + dimm->density = blk.spd_array[i][4] & 0xF; + dimm->size_gb = (1 << (dimm->density - 2)) * (2 - dimm->width) * + dimm->log_ranks; + + if ((blk.spd_array[i][5] & 0x38) == 0x30) + die("DIMMs with 18 row address bits are not supported\n"); + + if (blk.spd_array[i][18] > tckmin) + tckmin = blk.spd_array[i][18]; + } + } + + /* + * There is one (?) MCBIST per CPU. Fail if there are no supported DIMMs + * connected, otherwise assume it is functional. There is no reason to redo + * this test in the rest of isteps. + * + * TODO: 2 CPUs with one DIMM (in total) will not work with this code. + */ + if (mem_data.mcs[0].functional == false && mem_data.mcs[1].functional == false) + die("No DIMMs detected, aborting\n"); + + switch (tckmin) { + /* For CWL assume 1tCK write preamble */ + case 0x06: + mem_data.speed = 2666; + mem_data.cwl = 14; + break; + case 0x07: + mem_data.speed = 2400; + mem_data.cwl = 12; + break; + case 0x08: + mem_data.speed = 2133; + mem_data.cwl = 11; + break; + case 0x09: + mem_data.speed = 1866; + mem_data.cwl = 10; + break; + default: + die("Unsupported tCKmin: %d ps (+/- 125)\n", tckmin * 125); + } + + /* Now that we know our speed, we can calculate the rest of the data */ + mem_data.nrefi = ns_to_nck(7800); + mem_data.nrtp = ps_to_nck(7500); + printk(BIOS_SPEW, "Common memory parameters:\n" + "\tspeed =\t%d MT/s\n" + "\tREFI =\t%d clock cycles\n" + "\tCWL =\t%d clock cycles\n" + "\tRTP =\t%d clock cycles\n", + mem_data.speed, mem_data.nrefi, mem_data.cwl, mem_data.nrtp); + + for (mcs = 0; mcs < MCS_PER_PROC; mcs++) { + if (!mem_data.mcs[mcs].functional) continue; + for (mca = 0; mca < MCA_PER_MCS; mca++) { + if (!mem_data.mcs[mcs].mca[mca].functional) continue; + + rdimm_data_t *dimm = mem_data.mcs[mcs].mca[mca].dimm; + uint32_t val0, val1, common; + int min; /* Minimum compatible with both DIMMs is the bigger value */ + + /* CAS Latency */ + val0 = dimm[0].present ? le32_to_cpu(*(uint32_t *)&dimm[0].spd[20]) : -1; + val1 = dimm[1].present ? le32_to_cpu(*(uint32_t *)&dimm[1].spd[20]) : -1; + /* Assuming both DIMMs are in low CL range, true for all DDR4 speed bins */ + common = val0 & val1; + + /* tAAmin - minimum CAS latency time */ + min = find_min_mtb_ftb(dimm, 24, 123); + while (min <= 36 && ((common >> (min - 7)) & 1) == 0) + min++; + + if (min > 36) { + /* Maybe just die() instead? */ + printk(BIOS_WARNING, "Cannot find CL supported by all DIMMs under MCS%d, MCA%d." + " Marking as nonfunctional.\n", mcs, mca); + mark_nonfunctional(mcs, mca); + continue; + } + + mem_data.mcs[mcs].mca[mca].cl = min; + + /* + * There are also minimal values in Table 170 of JEDEC Standard No. 79-4C which + * probably should also be honored. Some of them (e.g. RRD) depend on the page + * size, which depends on DRAM width. On tested DIMM they are just right - it is + * either minimal legal value or rounded up to whole clock cycle. Can we rely on + * vendors to put sane values in SPD or do we have to check them for validity? + */ + + /* Minimum CAS to CAS Delay Time, Same Bank Group */ + mem_data.mcs[mcs].mca[mca].nccd_l = find_min_mtb_ftb(dimm, 40, 117); + + /* Minimum Write to Read Time, Different Bank Group */ + mem_data.mcs[mcs].mca[mca].nwtr_s = find_min_multi_mtb(dimm, 44, 43, 0x0F, 8); + + /* Minimum Write to Read Time, Same Bank Group */ + mem_data.mcs[mcs].mca[mca].nwtr_l = find_min_multi_mtb(dimm, 45, 43, 0xF0, 4); + + /* Minimum Four Activate Window Delay Time */ + mem_data.mcs[mcs].mca[mca].nfaw = find_min_multi_mtb(dimm, 37, 36, 0x0F, 8); + + /* Minimum RAS to CAS Delay Time */ + mem_data.mcs[mcs].mca[mca].nrcd = find_min_mtb_ftb(dimm, 25, 122); + + /* Minimum Row Precharge Delay Time */ + mem_data.mcs[mcs].mca[mca].nrp = find_min_mtb_ftb(dimm, 26, 121); + + /* Minimum Active to Precharge Delay Time */ + mem_data.mcs[mcs].mca[mca].nras = find_min_multi_mtb(dimm, 28, 27, 0x0F, 8); + + /* Minimum Write Recovery Time */ + mem_data.mcs[mcs].mca[mca].nwr = find_min_multi_mtb(dimm, 42, 41, 0x0F, 8); + + /* Minimum Activate to Activate Delay Time, Different Bank Group */ + mem_data.mcs[mcs].mca[mca].nrrd_s = find_min_mtb_ftb(dimm, 38, 119); + + /* Minimum Activate to Activate Delay Time, Same Bank Group */ + mem_data.mcs[mcs].mca[mca].nrrd_l = find_min_mtb_ftb(dimm, 39, 118); + + /* Minimum Refresh Recovery Delay Time */ + /* Assuming no fine refresh mode. */ + mem_data.mcs[mcs].mca[mca].nrfc = find_min_multi_mtb(dimm, 30, 31, 0xFF, 8); + + /* Minimum Refresh Recovery Delay Time for Different Logical Rank (3DS only) */ + /* + * This one is set per MCA, but it depends on DRAM density, which can be + * mixed between DIMMs under the same channel. We need to choose the bigger + * minimum time, which corresponds to higher density. + * + * Assuming no fine refresh mode. + */ + val0 = dimm[0].present ? dimm[0].spd[4] & 0xF : 0; + val1 = dimm[1].present ? dimm[1].spd[4] & 0xF : 0; + min = (val0 < val1) ? val1 : val0; + + switch (min) { + case 0x4: + mem_data.mcs[mcs].mca[mca].nrfc_dlr = ns_to_nck(90); + break; + case 0x5: + mem_data.mcs[mcs].mca[mca].nrfc_dlr = ns_to_nck(120); + break; + case 0x6: + mem_data.mcs[mcs].mca[mca].nrfc_dlr = ns_to_nck(185); + break; + default: + die("Unsupported DRAM density\n"); + } + + printk(BIOS_SPEW, "MCS%d, MCA%d times (in clock cycles):\n", mcs, mca); + dump_mca_data(&mem_data.mcs[mcs].mca[mca]); + } + } +} + +void main(void) +{ + timestamp_add_now(TS_START_ROMSTAGE); + + console_init(); + + init_timer(); + + timestamp_add_now(TS_BEFORE_INITRAM); + + vpd_pnor_main(); + prepare_dimm_data(); + + report_istep(13,1); // no-op + istep_8_9(); + istep_8_10(); + istep_13_2(); + istep_13_3(); + istep_13_4(); + report_istep(13,5); // no-op + istep_13_6(); + report_istep(13,7); // no-op + istep_13_8(); + istep_13_9(); + istep_13_10(); + istep_13_11(); + report_istep(13,12); // optional, not yet implemented + istep_13_13(); + + istep_14_1(); + istep_14_2(); + /* istep_14_3 doesn't work, probably due to missing SCOM init, skip for now. */ + // istep_14_3(); + report_istep(14,4); // no-op + istep_14_5(); + + timestamp_add_now(TS_AFTER_INITRAM); + + /* Test if SCOM still works. Maybe should check also indirect access? */ + printk(BIOS_DEBUG, "0xF000F = %llx\n", read_scom(0xf000f)); + + /* + * Halt to give a chance to inspect FIRs, otherwise checkstops from + * ramstage may cover up the failure in romstage. + */ + if (read_scom(0xf000f) != 0x223d104900008040) + die("SCOM stopped working, check FIRs, halting now\n"); + + cbmem_initialize_empty(); + run_ramstage(); +} diff --git a/src/soc/ibm/power9/timer.c b/src/soc/ibm/power9/timer.c new file mode 100644 index 00000000000..2e0289c0451 --- /dev/null +++ b/src/soc/ibm/power9/timer.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +void init_timer(void) +{ + // no need to do anything here +} diff --git a/util/cbfstool/flashmap/fmap.c b/util/cbfstool/flashmap/fmap.c index b7a748ce61f..4755a0604bb 100644 --- a/util/cbfstool/flashmap/fmap.c +++ b/util/cbfstool/flashmap/fmap.c @@ -35,7 +35,7 @@ int fmap_size(const struct fmap *fmap) if (!fmap) return -1; - return sizeof(*fmap) + (fmap->nareas * sizeof(struct fmap_area)); + return sizeof(*fmap) + (le16toh(fmap->nareas) * sizeof(struct fmap_area)); } /* Make a best-effort assessment if the given fmap is real */ @@ -47,8 +47,8 @@ static int is_valid_fmap(const struct fmap *fmap) if (fmap->ver_major != FMAP_VER_MAJOR) return 0; /* a basic consistency check: flash should be larger than fmap */ - if (fmap->size < - sizeof(*fmap) + fmap->nareas * sizeof(struct fmap_area)) + if (le32toh(fmap->size) < + sizeof(*fmap) + le16toh(fmap->nareas) * sizeof(struct fmap_area)) return 0; /* fmap-alikes along binary data tend to fail on having a valid, @@ -177,14 +177,14 @@ int fmap_print(const struct fmap *fmap) kv_pair_fmt(kv, "fmap_ver_major", "%d", fmap->ver_major); kv_pair_fmt(kv, "fmap_ver_minor","%d", fmap->ver_minor); kv_pair_fmt(kv, "fmap_base", "0x%016llx", - (unsigned long long)fmap->base); - kv_pair_fmt(kv, "fmap_size", "0x%04x", fmap->size); + (unsigned long long)le64toh(fmap->base)); + kv_pair_fmt(kv, "fmap_size", "0x%04x", le32toh(fmap->size)); kv_pair_fmt(kv, "fmap_name", "%s", fmap->name); - kv_pair_fmt(kv, "fmap_nareas", "%d", fmap->nareas); + kv_pair_fmt(kv, "fmap_nareas", "%d", le16toh(fmap->nareas)); kv_pair_print(kv); kv_pair_free(kv); - for (i = 0; i < fmap->nareas; i++) { + for (i = 0; i < le16toh(fmap->nareas); i++) { struct kv_pair *pair; uint16_t flags; char *str; @@ -194,16 +194,16 @@ int fmap_print(const struct fmap *fmap) return -1; kv_pair_fmt(pair, "area_offset", "0x%08x", - fmap->areas[i].offset); + le32toh(fmap->areas[i].offset)); kv_pair_fmt(pair, "area_size", "0x%08x", - fmap->areas[i].size); + le32toh(fmap->areas[i].size)); kv_pair_fmt(pair, "area_name", "%s", fmap->areas[i].name); kv_pair_fmt(pair, "area_flags_raw", "0x%02x", - fmap->areas[i].flags); + le16toh(fmap->areas[i].flags)); /* Print descriptive strings for flags rather than the field */ - flags = fmap->areas[i].flags; + flags = le16toh(fmap->areas[i].flags); str = fmap_flags_to_string(flags); if (str == NULL) { kv_pair_free(pair); @@ -265,8 +265,8 @@ struct fmap *fmap_create(uint64_t base, uint32_t size, uint8_t *name) memcpy(&fmap->signature, FMAP_SIGNATURE, strlen(FMAP_SIGNATURE)); fmap->ver_major = FMAP_VER_MAJOR; fmap->ver_minor = FMAP_VER_MINOR; - fmap->base = base; - fmap->size = size; + fmap->base = htole64(base); + fmap->size = htole32(size); memccpy(&fmap->name, name, '\0', FMAP_STRLEN); return fmap; @@ -289,7 +289,7 @@ int fmap_append_area(struct fmap **fmap, return -1; /* too many areas */ - if ((*fmap)->nareas >= 0xffff) + if (le16toh((*fmap)->nareas) >= 0xffff) return -1; orig_size = fmap_size(*fmap); @@ -301,12 +301,12 @@ int fmap_append_area(struct fmap **fmap, area = (struct fmap_area *)((uint8_t *)*fmap + orig_size); memset(area, 0, sizeof(*area)); - memcpy(&area->offset, &offset, sizeof(area->offset)); - memcpy(&area->size, &size, sizeof(area->size)); memccpy(&area->name, name, '\0', FMAP_STRLEN); - memcpy(&area->flags, &flags, sizeof(area->flags)); + area->offset = htole32(offset); + area->size = htole32(size); + area->flags = htole16(flags); - (*fmap)->nareas++; + (*fmap)->nareas = htole16(le16toh((*fmap)->nareas) + 1); return new_size; } @@ -319,7 +319,7 @@ const struct fmap_area *fmap_find_area(const struct fmap *fmap, if (!fmap || !name) return NULL; - for (i = 0; i < fmap->nareas; i++) { + for (i = 0; i < le16toh(fmap->nareas); i++) { if (!strcmp((const char *)fmap->areas[i].name, name)) { area = &fmap->areas[i]; break; @@ -358,12 +358,12 @@ static struct fmap *fmap_create_test(void) goto fmap_create_test_exit; } - if (fmap->base != base) { + if (le64toh(fmap->base) != base) { printf("FAILURE: base is incorrect\n"); goto fmap_create_test_exit; } - if (fmap->size != 0x100000) { + if (le32toh(fmap->size) != 0x100000) { printf("FAILURE: size is incorrect\n"); goto fmap_create_test_exit; } @@ -373,7 +373,7 @@ static struct fmap *fmap_create_test(void) goto fmap_create_test_exit; } - if (fmap->nareas != 0) { + if (le16toh(fmap->nareas) != 0) { printf("FAILURE: number of areas is incorrect\n"); goto fmap_create_test_exit; } @@ -414,10 +414,10 @@ static int fmap_append_area_test(struct fmap **fmap) uint16_t nareas_orig; /* test_area will be used by fmap_csum_test and find_area_test */ struct fmap_area test_area = { - .offset = 0x400, - .size = 0x10000, + .offset = htole32(0x400), + .size = htole32(0x10000), .name = "test_area_1", - .flags = FMAP_AREA_STATIC, + .flags = htole16(FMAP_AREA_STATIC), }; status = fail; @@ -428,26 +428,26 @@ static int fmap_append_area_test(struct fmap **fmap) goto fmap_append_area_test_exit; } - nareas_orig = (*fmap)->nareas; - (*fmap)->nareas = ~(0); + nareas_orig = le16toh((*fmap)->nareas); + (*fmap)->nareas = htole16(~(0)); if (fmap_append_area(fmap, 0, 0, (const uint8_t *)"foo", 0) >= 0) { printf("FAILURE: failed to abort with too many areas\n"); goto fmap_append_area_test_exit; } - (*fmap)->nareas = nareas_orig; + (*fmap)->nareas = htole16(nareas_orig); total_size = sizeof(**fmap) + sizeof(test_area); if (fmap_append_area(fmap, - test_area.offset, - test_area.size, + le32toh(test_area.offset), + le32toh(test_area.size), test_area.name, - test_area.flags + le16toh(test_area.flags) ) != total_size) { printf("failed to append area\n"); goto fmap_append_area_test_exit; } - if ((*fmap)->nareas != 1) { + if (le16toh((*fmap)->nareas) != 1) { printf("FAILURE: failed to increment number of areas\n"); goto fmap_append_area_test_exit; }