-
Notifications
You must be signed in to change notification settings - Fork 0
[on hold] OCC operations #89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: talos_2_support_payload
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0-only */ | ||
|
|
||
| #ifndef CPU_PPC64_OCC_H | ||
| #define CPU_PPC64_OCC_H | ||
|
|
||
| #include <cpu/power/scom.h> | ||
|
|
||
| #define OCC_405_SRAM_ADDRESS (0xFFF40000) | ||
| #define OCC_OFFSET_MAIN_EP (0x6C) | ||
| #define OCC_BRANCH_INSTR (0x4B00000200000000) | ||
| #define BRANCH_ADDR_MASK (0x00FFFFFC) | ||
|
|
||
| #define OCB_PIB_OCBCSR0_OCB_STREAM_MODE (4) | ||
| #define OCB_PIB_OCBCSR0_OCB_STREAM_TYPE (5) | ||
|
|
||
| #define OCB_OCI_OCBSHCS0_PUSH_ENABLE (31) | ||
| #define OCB_OCI_OCBSHCS0_PUSH_FULL (0) | ||
|
|
||
| #define PU_OCB_PIB_OCBCSR0_RO (0x0006D011) | ||
| #define PU_OCB_OCI_OCBSHCS0_SCOM (0x0006C204) | ||
| #define PU_OCB_PIB_OCBDR0 (0x0006D015) | ||
|
|
||
| #define PU_OCB_PIB_OCBCSR0_OR (0x0006D013) | ||
| #define PU_OCB_PIB_OCBCSR1_OR (0x0006D033) | ||
| #define PU_OCB_PIB_OCBCSR2_OR (0x0006D053) | ||
| #define PU_OCB_PIB_OCBCSR3_OR (0x0006D073) | ||
|
|
||
| #define PU_OCB_PIB_OCBCSR0_CLEAR (0x0006D012) | ||
| #define PU_OCB_PIB_OCBCSR1_CLEAR (0x0006D032) | ||
| #define PU_OCB_PIB_OCBCSR2_CLEAR (0x0006D052) | ||
| #define PU_OCB_PIB_OCBCSR3_CLEAR (0x0006D072) | ||
|
|
||
| #define PU_OCB_PIB_OCBAR0 (0x0006D010) | ||
| #define PU_OCB_PIB_OCBAR1 (0x0006D030) | ||
| #define PU_OCB_PIB_OCBAR2 (0x0006D050) | ||
| #define PU_OCB_PIB_OCBAR3 (0x0006D070) | ||
|
|
||
| #define EX_PPM_SPWKUP_OCC (0x200F010C) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here you use |
||
|
|
||
| #define NUMBER_OF_EX_CHIPLETS (6) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where does it come from? AFAIK there are 12 EXs, 2 per EQ, even though they are probably waken in pairs. |
||
| const chiplet_id_t EX_CHIPLETS[NUMBER_OF_EX_CHIPLETS] = | ||
| { | ||
| EP00_CHIPLET_ID, | ||
| EP01_CHIPLET_ID, | ||
| EP02_CHIPLET_ID, | ||
| EP03_CHIPLET_ID, | ||
| EP04_CHIPLET_ID, | ||
| EP05_CHIPLET_ID | ||
| }; | ||
|
Comment on lines
+42
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Something wrong with indentation here. |
||
|
|
||
| const uint64_t OCBARn[4] = | ||
| { | ||
| PU_OCB_PIB_OCBAR0, | ||
| PU_OCB_PIB_OCBAR1, | ||
| PU_OCB_PIB_OCBAR2, | ||
| PU_OCB_PIB_OCBAR3 | ||
| }; | ||
|
|
||
| const uint64_t OCBCSRn_CLEAR[4] = | ||
| { | ||
| PU_OCB_PIB_OCBCSR0_CLEAR, | ||
| PU_OCB_PIB_OCBCSR1_CLEAR, | ||
| PU_OCB_PIB_OCBCSR2_CLEAR, | ||
| PU_OCB_PIB_OCBCSR3_CLEAR | ||
| }; | ||
|
|
||
| const uint64_t OCBCSRn_OR[4] = | ||
| { | ||
| PU_OCB_PIB_OCBCSR0_OR, | ||
| PU_OCB_PIB_OCBCSR1_OR, | ||
| PU_OCB_PIB_OCBCSR2_OR, | ||
| PU_OCB_PIB_OCBCSR3_OR | ||
| }; | ||
|
|
||
| void writeOCCSRAM( | ||
| const uint32_t address, | ||
| uint64_t * buffer, | ||
| size_t data_length); | ||
| void readOCCSRAM( | ||
| const uint32_t address, | ||
| uint64_t * buffer, | ||
| size_t data_length); | ||
| uint64_t makeStart405Instruction(void); | ||
| void clear_occ_special_wakeups(void); | ||
|
|
||
| #endif /* CPU_PPC64_OCC_H */ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0-only */ | ||
|
|
||
| #include <cpu/power/scom.h> | ||
| #include <cpu/power/occ.h> | ||
| #include <timer.h> | ||
|
|
||
|
|
||
| static void pm_ocb_setup(const uint32_t i_ocb_bar) | ||
| { | ||
| write_scom(OCBCSRn_OR[0], PPC_BIT(OCB_PIB_OCBCSR0_OCB_STREAM_MODE)); | ||
| write_scom(OCBCSRn_CLEAR[0], PPC_BIT(OCB_PIB_OCBCSR0_OCB_STREAM_TYPE)); | ||
| write_scom(OCBARn[0], (uint64_t)i_ocb_bar << 32); | ||
| } | ||
|
|
||
| static void put_ocb_indirect( | ||
| const uint32_t i_ocb_req_length, | ||
| const uint32_t i_oci_address, | ||
| uint64_t* io_ocb_buffer) | ||
| { | ||
| write_scom(PU_OCB_PIB_OCBAR0, (uint64_t)i_oci_address << 32); | ||
| uint64_t ocb_pib = read_scom(PU_OCB_PIB_OCBCSR0_RO); | ||
| if((ocb_pib & OCB_PIB_OCBCSR0_OCB_STREAM_MODE) | ||
| && (ocb_pib & OCB_PIB_OCBCSR0_OCB_STREAM_TYPE)) | ||
|
Comment on lines
+22
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if this is at the same indentation level or GitHub just displays it that way, but the second line should begin under next character after first bracket. |
||
| { | ||
| uint64_t stream_push_control = read_scom(PU_OCB_OCI_OCBSHCS0_SCOM); | ||
| if (stream_push_control & OCB_OCI_OCBSHCS0_PUSH_ENABLE) | ||
| for(uint8_t l_counter = 0; l_counter < 4; l_counter++) | ||
|
Comment on lines
+26
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indentation. |
||
| { | ||
| if (!(stream_push_control & OCB_OCI_OCBSHCS0_PUSH_FULL)) | ||
| { | ||
| break; | ||
| } | ||
| // Hostboot has delay of 0 here | ||
| wait_us(1, false); | ||
| stream_push_control = read_scom(PU_OCB_OCI_OCBSHCS0_SCOM); | ||
| } | ||
| } | ||
| for(uint32_t l_index = 0; l_index < i_ocb_req_length; l_index++) | ||
| { | ||
| write_scom(PU_OCB_PIB_OCBDR0, io_ocb_buffer[l_index]); | ||
| } | ||
| } | ||
|
|
||
| static void get_ocb_indirect( | ||
| const uint32_t i_ocb_req_length, | ||
| const uint32_t i_oci_address, | ||
| uint64_t* io_ocb_buffer) | ||
| { | ||
| write_scom(PU_OCB_PIB_OCBAR0, (uint64_t)i_oci_address << 32); | ||
| for(uint32_t l_loopCount = 0; l_loopCount < i_ocb_req_length; l_loopCount++) | ||
| { | ||
| io_ocb_buffer[l_loopCount] = read_scom(PU_OCB_PIB_OCBDR0); | ||
| } | ||
| } | ||
|
|
||
| void writeOCCSRAM( | ||
| const uint32_t address, | ||
| uint64_t * buffer, | ||
| size_t data_length) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add a low verbosity print if this isn't a multiply of 8, here and for read. |
||
| { | ||
| pm_ocb_setup(address); | ||
| put_ocb_indirect( | ||
| data_length / 8, | ||
| address, | ||
| buffer); | ||
| } | ||
|
|
||
| void readOCCSRAM( | ||
| const uint32_t address, | ||
| uint64_t * buffer, | ||
| size_t data_length) | ||
| { | ||
| pm_ocb_setup(address); | ||
| get_ocb_indirect( | ||
| data_length / 8, | ||
| address, | ||
| buffer); | ||
| } | ||
|
|
||
| uint64_t makeStart405Instruction(void) | ||
| { | ||
| uint64_t l_epAddr; | ||
| readOCCSRAM( | ||
| OCC_405_SRAM_ADDRESS + OCC_OFFSET_MAIN_EP, | ||
| &l_epAddr, | ||
| 8); | ||
|
|
||
| // The branch instruction is of the form 0x4BXXXXX200000000, where X | ||
| // is the address of the 405 main's entry point (alligned as shown). | ||
| // Example: If 405 main's EP is FFF5B570, then the branch instruction | ||
| // will be 0x4bf5b57200000000. The last two bits of the first byte of | ||
| // the branch instruction must be '2' according to the OCC instruction | ||
| // set manual. | ||
|
Comment on lines
+91
to
+93
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this comment copied from Hostboot? That |
||
| return OCC_BRANCH_INSTR | (((uint64_t)(BRANCH_ADDR_MASK & l_epAddr)) << 32); | ||
| } | ||
|
|
||
| void clear_occ_special_wakeups(void) | ||
| { | ||
| for(size_t chiplet_index = 0; | ||
| chiplet_index < NUMBER_OF_EX_CHIPLETS; | ||
| ++chiplet_index) | ||
| { | ||
| write_scom_for_chiplet( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| EX_CHIPLETS[chiplet_index], | ||
| EX_PPM_SPWKUP_OCC, | ||
| read_scom_for_chiplet(EX_CHIPLETS[chiplet_index], | ||
| EX_PPM_SPWKUP_OCC) & ~PPC_BIT(0)); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://wiki.raptorcs.com/w/images/9/9b/405_um.pdf page 199