/****************************************************************************** * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License * which accompanies this distribution, and is available at * http://www.opensource.org/licenses/bsd-license.php * * Contributors: * IBM Corporation - initial implementation *****************************************************************************/ #include #include #include "rtas_board.h" #include #include #include #include "libipmi.h" #include void io_init(void); short reg_get_flashside(void); void rtas_init(void); typedef struct { uint64_t r3; uint64_t addr; volatile uint64_t id; } slave_t; volatile slave_t rtas_slave_interface; static void rtas_slave_loop(volatile slave_t * pIface) { uint64_t mask = pIface->id; pIface->id = 0; while (pIface->id != mask); { int dly = 0x1000; while (dly--); } pIface->id = 0; asm volatile (" mr 3,%0 ; mtctr %1 ; bctr " ::"r"(pIface->r3), "r"(pIface->addr)); } void rtas_fetch_slaves(rtas_args_t * pArgs) { int retVal = 0; int idx = 0; uint32_t mask = pArgs->args[0] & 0xFFFFFFFE; uint64_t *rtas_slave_loop_ptr = (uint64_t *)rtas_slave_loop; while (mask) { if (mask & 0x1) { rtas_slave_interface.id = idx | 0x100; *(int *) 0x3fc0 = (int)(unsigned long) &rtas_slave_interface; // r3 *(int *) 0x3f80 = *rtas_slave_loop_ptr; // addr *(int *) 0x3fa0 = idx | 0x100; // pid while (rtas_slave_interface.id); } mask >>= 1; idx++; } pArgs->args[pArgs->nargs] = retVal; } void rtas_start_cpu(rtas_args_t * pArgs) { int retVal = 0; int idx = pArgs->args[0]; // pid rtas_slave_interface.r3 = pArgs->args[2]; // r3 rtas_slave_interface.addr = pArgs->args[1]; // addr asm(" sync "); rtas_slave_interface.id = idx | 0x100; // pid while (rtas_slave_interface.id); pArgs->args[pArgs->nargs] = retVal; } void rtas_read_vpd(rtas_args_t * pArgs) { pArgs->args[pArgs->nargs] = bmc_read_vpd((uint8_t *) (uint64_t) pArgs->args[2], pArgs->args[1], pArgs->args[0]); } void rtas_write_vpd(rtas_args_t * pArgs) { pArgs->args[pArgs->nargs] = bmc_write_vpd((uint8_t *) (uint64_t) pArgs->args[2], pArgs->args[1], pArgs->args[0]); } void rtas_set_indicator(rtas_args_t * pArgs) { pArgs->args[pArgs->nargs] = -1; } void rtas_event_scan(rtas_args_t * pArgs) { pArgs->args[pArgs->nargs] = -1; } void rtas_stop_bootwatchdog(rtas_args_t * pArgs) { pArgs->args[pArgs->nargs] = bmc_stop_bootwatchdog(); } void rtas_set_bootwatchdog(rtas_args_t * pArgs) { pArgs->args[pArgs->nargs] = bmc_set_bootwatchdog(pArgs->args[0]); } void rtas_set_flashside(rtas_args_t * pArgs) { pArgs->args[pArgs->nargs] = bmc_set_flashside(pArgs->args[0]); } void rtas_get_flashside(rtas_args_t * pArgs) { int retVal = bmc_get_flashside(); pArgs->args[pArgs->nargs] = retVal; } void rtas_flash_test(rtas_args_t * pArgs) { pArgs->args[pArgs->nargs] = -1; } void rtas_system_reboot(rtas_args_t * pArgs) { bmc_system_reboot(); pArgs->args[pArgs->nargs] = -1; } void rtas_power_off(rtas_args_t * pArgs) { bmc_power_off(); pArgs->args[pArgs->nargs] = -1; } void rtas_get_blade_descr(rtas_args_t * pArgs) { uint8_t *buffer = (uint8_t *) (uint64_t) pArgs->args[0]; uint32_t maxlen = pArgs->args[1]; uint32_t retlen = 0; uint32_t retval = bmc_get_blade_descr(buffer, maxlen, &retlen); pArgs->args[pArgs->nargs] = retlen; pArgs->args[pArgs->nargs + 1] = retval; } // for JS20 cannot read blade descr static uint32_t dummy_get_blade_descr(uint8_t *dst, uint32_t maxlen, uint32_t *len) { // to not have a warning we need to do _something_ with *dst and maxlen... *dst = *dst; maxlen = maxlen; *len = 0; return -1; } /* read flashside from register */ short reg_get_flashside(void) { short retVal; uint8_t val = load8_ci(0xf4003fe3); if (val & 0x80) { // temp retVal = 1; } else { // perm retVal = 0; } return retVal; } void rtas_init(void) { io_init(); if (u4Flag) { bmc_system_reboot = ipmi_system_reboot; bmc_power_off = ipmi_power_off; bmc_set_flashside = ipmi_set_flashside; bmc_get_flashside = reg_get_flashside; bmc_stop_bootwatchdog = ipmi_oem_stop_bootwatchdog; bmc_set_bootwatchdog = ipmi_oem_set_bootwatchdog; bmc_read_vpd = ipmi_oem_read_vpd; bmc_write_vpd = ipmi_oem_write_vpd; bmc_get_blade_descr = ipmi_oem_get_blade_descr; } else { bmc_system_reboot = i2c_system_reboot; bmc_power_off = i2c_power_off; bmc_set_flashside = i2c_set_flashside; bmc_get_flashside = i2c_get_flashside; bmc_stop_bootwatchdog = i2c_stop_bootwatchdog; bmc_set_bootwatchdog = i2c_set_bootwatchdog; bmc_read_vpd = i2c_read_vpd; bmc_write_vpd = i2c_write_vpd; bmc_get_blade_descr = dummy_get_blade_descr; } }