Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * simos_rtas.c
- *
- * Simulate the actions of RS/6000 RTAS (Run Time Abstraction Services)
- * as appropriate for the simulated CPU(s) of SimOS-PPC
- *
- * The (simulated) operating system calls the single RTAS service routine
- * with a pointer to a parameter list like this:
- *
- * R3 points here ----> Token (indicates function to be performed)
- * No. of inputs, n
- * No. of outputs, m
- * Input value 1
- * Input value 2
- * ...
- * Input value n
- * Output value 1
- * ...
- * Output value m
- *
- * The parameter list is 8-byte aligned in (simulated) REAL storage;
- * the call is made with address translation off (MSR bits IR and DR
- * are both 0) and in supervisor state (MSR bit PR is 0).
- *
- * Each "cell" in the parameter list is a 32-bit integer, even on a 64-bit
- * simulated machine, because there is no 64-bit version of RTAS yet.
- *
- * Token values (for SimOS-PPC's RTAS) are defined in simos_rtas.h.
- * All defined values are accepted, but many are treated here as no-ops.
- *
- * This routine, semantic_rtascall(), is the semantic routine for an
- * undefined PowerPC instruction that is used to interface the simulated
- * operating system with the RTAS functions provided by SimOS.
- */
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <time.h>
- #include <sys/types.h>
- #include <ctype.h>
- #include "ppc.h"
- #include "addr_layout.h"
- #include "sim_error.h"
- #include "simos_rtas.h"
- typedef struct {
- uint32 token;
- uint32 num_inputs;
- uint32 num_outputs;
- int32 values[1];
- } RTAS_parms;
- /*
- * semantic_rtascall ()
- */
- int semantic_rtascall (PowerPCState *P, Inst ins)
- {
- PA parms_pa = P->gpr[3];
- RTAS_parms *parms = (RTAS_parms *) PHYS_TO_MEMADDR (M_FROM_CPU (P->myNum), parms_pa);
- int32 *in_parms = &parms->values[0];
- int32 *out_parms = &parms->values[parms->num_inputs];
- #ifndef K42
- #if 1 /* PJB */
- ASSERT(0); /* MAKE CACHE-ENABLED */
- #endif
- #endif
- switch (parms->token) {
- /*
- * Get UTC time of day
- */
- case RTAS_get_time_of_day: {
- time_t curtim = time (NULL);
- struct tm *gmt = gmtime (&curtim);
- out_parms[1] = gmt->tm_year + 1900; /* tm_year is year-1900 */
- out_parms[2] = gmt->tm_mon + 1; /* tm_mon is 0..11, output wants 1..12 */
- out_parms[3] = gmt->tm_mday; /* day of month 1..31 */
- out_parms[4] = gmt->tm_hour; /* hour 0..23 */
- out_parms[5] = gmt->tm_min; /* minute 0..59 */
- out_parms[6] = gmt->tm_sec; /* second 0..59 */
- out_parms[7] = 0; /* nanoseconds */
- CPUWarning ("cpu[%d] RTAS get-time-of-day\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- }
- /*
- * Set UTC time of day
- * FIXME -- we'll need to do something with this
- */
- case RTAS_set_time_of_day:
- CPUWarning ("cpu[%d] RTAS set-time-of-day\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- /*
- * Scan for reasons for interrupting
- */
- case RTAS_event_scan:
- CPUWarning ("cpu[%d] RTAS event-scan\n", P->myNum);
- out_parms[0] = 1; /* no errors found */
- break;
- /*
- * Scan for hardware errors
- */
- case RTAS_check_exception:
- CPUWarning ("cpu[%d] RTAS check-exception\n", P->myNum);
- out_parms[0] = 1; /* no errors found */
- break;
- /*
- * Give detail on last error in RTAS' log
- */
- case RTAS_last_error:
- CPUWarning ("cpu[%d] RTAS last-error\n", P->myNum);
- out_parms[0] = 1; /* no errors found */
- break;
- /*
- * Read PCI configuration register (need a real function here -- FIXME)
- */
- case RTAS_read_pci_config:
- CPUWarning ("cpu[%d] RTAS read-pci-config\n", P->myNum);
- out_parms[0] = 0; /* success */
- out_parms[1] = 0; /* value read (bogus) */
- break;
- /*
- * Write PCI configuration register (need a real function here -- FIXME)
- */
- case RTAS_write_pci_config:
- CPUWarning ("cpu[%d] RTAS write-pci-config\n", P->myNum);
- out_parms[0] = 0; /* success -- but we haven't written anything */
- break;
- /*
- * Write one character to alpha-numeric error/status display device
- */
- case RTAS_display_character: {
- char c = in_parms[0];
- char disp[8];
- if (isprint (c)) {
- disp[0] = c;
- disp[1] = '\0';
- }
- else switch (c) {
- case '\n': strcpy (disp, "\\n"); break;
- case '\t': strcpy (disp, "\\t"); break;
- case '\b': strcpy (disp, "\\b"); break;
- case '\f': strcpy (disp, "\\f"); break;
- case '\r': strcpy (disp, "\\r"); break;
- default: sprintf (disp, "0x%.2X", c); break;
- }
- CPUWarning ("cpu[%d] RTAS display-character '%s'\n", P->myNum, disp);
- out_parms[0] = 0; /* success */
- break;
- }
- /*
- * Set indicator (hex display, output tone, disk light, etc.)
- * We'll claim we don't have any of these.
- */
- case RTAS_set_indicator:
- CPUWarning ("cpu[%d] RTAS set-indicator\n", P->myNum);
- out_parms[0] = -3; /* "no such indicator implemented" */
- break;
- /*
- * Get sensor state (fan speed, power supply voltage, etc.)
- * If the requested sensor is the key switch, we'll reply "normal mode".
- * For other sensors, we'll claim we have no such.
- */
- case RTAS_get_sensor_state:
- CPUWarning ("cpu[%d] RTAS get-sensor-state (%d)\n", P->myNum, in_parms[0]);
- if (1 == in_parms[0]) { /* test for key switch */
- out_parms[0] = 0; /* success */
- out_parms[1] = 1; /* normal mode */
- }
- else
- out_parms[0] = -3; /* "no such sensor implemented" */
- break;
- /*
- * Get current power level (highest speed, battery saver, etc.)
- * We'll claim we can't find this out.
- */
- case RTAS_get_power_level:
- CPUWarning ("cpu[%d] RTAS get-power-level\n", P->myNum);
- out_parms[0] = -3; /* "can't determine current level" */
- break;
- /*
- * Power-off: Turn off the AC power.
- * We'll claim we can't do this.
- */
- case RTAS_power_off:
- CPUWarning ("cpu[%d] RTAS power-off\n", P->myNum);
- out_parms[0] = -1; /* "hardware error" */
- break;
- /*
- * Suspend, hibernate: Save memory, power down.
- * We'll claim we can't do this.
- */
- case RTAS_hibernate:
- CPUWarning ("cpu[%d] RTAS hibernate\n", P->myNum);
- out_parms[0] = -1;
- break;
- case RTAS_suspend:
- CPUWarning ("cpu[%d] RTAS suspend\n", P->myNum);
- out_parms[0] = -1; /* "hardware error" */
- break;
- /*
- * Reboot: Re-IPL the system
- */
- case RTAS_system_reboot:
- CPUWarning ("cpu[%d] RTAS reboot.............\n", P->myNum);
- out_parms[0] = 0; /* FIXME -- we need actually to reboot */
- break;
- /*
- * Update flash memory and optionally reboot
- * Claim we can't do this.
- */
- case RTAS_update_flash:
- case RTAS_update_flash_and_reboot:
- case RTAS_ibm_update_flash_64_and_reboot:
- case RTAS_ibm_update_flash_64:
- CPUWarning ("cpu[%d] RTAS update-flash etc.\n", P->myNum);
- out_parms[0] = -1; /* "hardware error" covers a multitude of ills */
- break;
- /*
- * Cache control
- * We'll need an actual function here; for now, just return "success"
- */
- case RTAS_cache_control:
- CPUWarning ("cpu[%d] RTAS cache-control (cache %d, state %d)\n",
- P->myNum, in_parms[0], in_parms[1]);
- out_parms[0] = 0; /* success */
- break;
- /*
- * Freeze time base (stop time base updates for all processors in SMP)
- * We'll need an actual function here; for now, just return "success"
- */
- case RTAS_freeze_time_base:
- CPUWarning ("cpu[%d] RTAS freeze-time-base\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- /*
- * Thaw time base (restart time base updates for all processors in SMP)
- * We'll need an actual function here; for now, just return "success"
- */
- case RTAS_thaw_time_base:
- CPUWarning ("cpu[%d] RTAS thaw-time-base\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- /*
- * Stop self -- stop this processor in SMP
- * We'll need an actual function here; for now, just return "success"
- */
- case RTAS_stop_self:
- CPUWarning ("cpu[%d] RTAS stop-self\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- /*
- * Start CPU -- Start an SMP processor
- * We'll need an actual function here; for now, just return "success"
- */
- case RTAS_start_cpu:
- CPUWarning ("cpu[%d] RTAS start-cpu (cpu=%d, locn=0x%.8X, r3=0x%.8X\n",
- P->myNum, in_parms[0], in_parms[1], in_parms[2]);
- out_parms[0] = 0; /* success */
- break;
- /*
- * Query CPU stopped state -- check run/stopped state of another processor in SMP
- * We'll need an actual function here; for now, just return "hardware error"
- * to indicate we don't know.
- */
- case RTAS_query_cpu_stopped_state:
- CPUWarning ("cpu[%d] RTAS query-cpu-stopped-state (cpu=%d)\n",
- P->myNum, in_parms[0]);
- out_parms[0] = -1; /* "hardware error" */
- break;
- /*
- * os-term: OS is terminating.
- * Print the string passed by the OS.
- */
- case RTAS_ibm_os_term: {
- PA str_pa = in_parms[0];
- char * str = (char *) PHYS_TO_MEMADDR (M_FROM_CPU (P->myNum), str_pa);
- CPUWarning ("cpu[%d] RTAS os-term: \"%s\"\n", P->myNum, str);
- out_parms[0] = 0; /* success */
- break;
- }
- /*
- * For each of these, do nothing but return a "success" indication (out_parms[0] <- 0)
- */
- case RTAS_restart:
- CPUWarning ("cpu[%d] RTAS restart-tras\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- case RTAS_nvram_fetch:
- CPUWarning ("cpu[%d] RTAS nvram-fetch\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- case RTAS_nvram_store:
- CPUWarning ("cpu[%d] RTAS nvram-store\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- case RTAS_set_time_for_power_on:
- CPUWarning ("cpu[%d] RTAS set-time-for-power-on\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- case RTAS_set_power_level:
- CPUWarning ("cpu[%d] RTAS set-power-level\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- case RTAS_assume_power_management:
- CPUWarning ("cpu[%d] RTAS assume-power-management\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- case RTAS_relinquish_power_management:
- CPUWarning ("cpu[%d] RTAS relinquish-power-management\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- case RTAS_ibm_exti2c:
- CPUWarning ("cpu[%d] RTAS exti2c\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- case RTAS_ibm_refresh_firmware_parameters:
- CPUWarning ("cpu[%d] RTAS refresh-firmware-parameters\n", P->myNum);
- out_parms[0] = 0; /* success */
- break;
- }
- P->PC += sizeof (Inst);
- return TRUE;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement