| /* Copyright 2013-2014 IBM Corp. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| * implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| #include <skiboot.h> |
| #include <chip.h> |
| #include <device.h> |
| #include <timebase.h> |
| |
| static struct proc_chip *chips[MAX_CHIPS]; |
| enum proc_chip_quirks proc_chip_quirks; |
| |
| uint32_t pir_to_chip_id(uint32_t pir) |
| { |
| if (proc_gen == proc_gen_p9) |
| return P9_PIR2GCID(pir); |
| else if (proc_gen == proc_gen_p8) |
| return P8_PIR2GCID(pir); |
| else |
| return P7_PIR2GCID(pir); |
| } |
| |
| uint32_t pir_to_core_id(uint32_t pir) |
| { |
| if (proc_gen == proc_gen_p9) |
| return P9_PIR2COREID(pir); |
| else if (proc_gen == proc_gen_p8) |
| return P8_PIR2COREID(pir); |
| else |
| return P7_PIR2COREID(pir); |
| } |
| |
| uint32_t pir_to_thread_id(uint32_t pir) |
| { |
| if (proc_gen == proc_gen_p9) |
| return P9_PIR2THREADID(pir); |
| else if (proc_gen == proc_gen_p8) |
| return P8_PIR2THREADID(pir); |
| else |
| return P7_PIR2THREADID(pir); |
| } |
| |
| struct proc_chip *next_chip(struct proc_chip *chip) |
| { |
| unsigned int i; |
| |
| for (i = chip ? (chip->id + 1) : 0; i < MAX_CHIPS; i++) |
| if (chips[i]) |
| return chips[i]; |
| return NULL; |
| } |
| |
| |
| struct proc_chip *get_chip(uint32_t chip_id) |
| { |
| if (chip_id >= MAX_CHIPS) |
| return NULL; |
| return chips[chip_id]; |
| } |
| |
| void init_chips(void) |
| { |
| struct proc_chip *chip; |
| struct dt_node *xn; |
| |
| /* Detect mambo chip */ |
| if (dt_find_by_path(dt_root, "/mambo")) { |
| proc_chip_quirks |= QUIRK_NO_CHIPTOD | QUIRK_MAMBO_CALLOUTS |
| | QUIRK_NO_F000F | QUIRK_NO_PBA | QUIRK_NO_OCC_IRQ |
| | QUIRK_NO_DIRECT_CTL | QUIRK_NO_RNG; |
| prlog(PR_NOTICE, "CHIP: Detected Mambo simulator\n"); |
| } |
| /* Detect simics */ |
| if (dt_find_by_path(dt_root, "/simics")) { |
| proc_chip_quirks |= QUIRK_SIMICS |
| | QUIRK_NO_PBA | QUIRK_NO_OCC_IRQ | QUIRK_SLOW_SIM; |
| tb_hz = 512000; |
| prlog(PR_NOTICE, "CHIP: Detected Simics simulator\n"); |
| } |
| /* Detect Awan emulator */ |
| if (dt_find_by_path(dt_root, "/awan")) { |
| proc_chip_quirks |= QUIRK_NO_CHIPTOD | QUIRK_NO_F000F |
| | QUIRK_NO_PBA | QUIRK_NO_OCC_IRQ | QUIRK_SLOW_SIM; |
| tb_hz = 512000; |
| prlog(PR_NOTICE, "CHIP: Detected Awan emulator\n"); |
| } |
| /* Detect Qemu */ |
| if (dt_node_is_compatible(dt_root, "qemu,powernv")) { |
| proc_chip_quirks |= QUIRK_NO_CHIPTOD | QUIRK_NO_PBA |
| | QUIRK_NO_DIRECT_CTL; |
| prlog(PR_NOTICE, "CHIP: Detected Qemu simulator\n"); |
| } |
| |
| /* We walk the chips based on xscom nodes in the tree */ |
| dt_for_each_compatible(dt_root, xn, "ibm,xscom") { |
| uint32_t id = dt_get_chip_id(xn); |
| |
| assert(id < MAX_CHIPS); |
| |
| chip = zalloc(sizeof(struct proc_chip)); |
| assert(chip); |
| chip->id = id; |
| chip->devnode = xn; |
| chips[id] = chip; |
| chip->dbob_id = dt_prop_get_u32_def(xn, "ibm,dbob-id", |
| 0xffffffff); |
| chip->pcid = dt_prop_get_u32_def(xn, "ibm,proc-chip-id", |
| 0xffffffff); |
| if (dt_prop_get_u32_def(xn, "ibm,occ-functional-state", 0)) |
| chip->occ_functional = true; |
| else |
| chip->occ_functional = false; |
| |
| list_head_init(&chip->i2cms); |
| }; |
| } |