backdoor.cc revision 873
12SN/A/* 29235Sandreas.hansson@arm.com * Copyright (c) 2003 The Regents of The University of Michigan 39235Sandreas.hansson@arm.com * All rights reserved. 49235Sandreas.hansson@arm.com * 59235Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 69235Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 79235Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 89235Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 99235Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 109235Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 119235Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 129235Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 139235Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 141762SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272SN/A */ 282SN/A 292SN/A/* @file 302SN/A * System Console Definition 312SN/A */ 322SN/A 332SN/A#include <cstddef> 342SN/A#include <cstdio> 352SN/A#include <string> 362SN/A 372SN/A#include "base/inifile.hh" 382SN/A#include "base/str.hh" // for to_number() 392665SN/A#include "base/trace.hh" 402665SN/A#include "cpu/base_cpu.hh" 412665SN/A#include "cpu/exec_context.hh" 429235Sandreas.hansson@arm.com#include "dev/alpha_console.hh" 432SN/A#include "dev/console.hh" 442SN/A#include "dev/simple_disk.hh" 459235Sandreas.hansson@arm.com#include "dev/tlaser_clock.hh" 469235Sandreas.hansson@arm.com#include "mem/bus/bus.hh" 472SN/A#include "mem/bus/pio_interface.hh" 4810481Sandreas.hansson@arm.com#include "mem/bus/pio_interface_impl.hh" 499412Sandreas.hansson@arm.com#include "mem/functional_mem/memory_control.hh" 509412Sandreas.hansson@arm.com#include "sim/builder.hh" 519411Sandreas.hansson@arm.com#include "sim/system.hh" 529405Sandreas.hansson@arm.com#include "dev/tsunami_io.hh" 539411Sandreas.hansson@arm.com#include "sim/sim_object.hh" 549235Sandreas.hansson@arm.com#include "targetarch/byte_swap.hh" 559235Sandreas.hansson@arm.com 569235Sandreas.hansson@arm.comusing namespace std; 572SN/A 582SN/AAlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, 599405Sandreas.hansson@arm.com System *system, BaseCPU *cpu, SimObject *clock, 609405Sandreas.hansson@arm.com int num_cpus, MemoryController *mmu, Addr a, 619411Sandreas.hansson@arm.com HierParams *hier, Bus *bus) 6210435Snilay@cs.wisc.edu : PioDevice(name), disk(d), console(cons), addr(a) 639405Sandreas.hansson@arm.com{ 649405Sandreas.hansson@arm.com mmu->add_child(this, Range<Addr>(addr, addr + size)); 659405Sandreas.hansson@arm.com 669411Sandreas.hansson@arm.com if (bus) { 679411Sandreas.hansson@arm.com pioInterface = newPioInterface(name, hier, bus, this, 689411Sandreas.hansson@arm.com &AlphaConsole::cacheAccess); 699411Sandreas.hansson@arm.com pioInterface->addAddrRange(addr, addr + size); 709411Sandreas.hansson@arm.com } 719411Sandreas.hansson@arm.com 729411Sandreas.hansson@arm.com alphaAccess->last_offset = size - 1; 739411Sandreas.hansson@arm.com alphaAccess->kernStart = system->getKernelStart(); 749411Sandreas.hansson@arm.com alphaAccess->kernEnd = system->getKernelEnd(); 759411Sandreas.hansson@arm.com alphaAccess->entryPoint = system->getKernelEntry(); 769235Sandreas.hansson@arm.com 772SN/A alphaAccess->version = ALPHA_ACCESS_VERSION; 789235Sandreas.hansson@arm.com alphaAccess->numCPUs = num_cpus; 799411Sandreas.hansson@arm.com alphaAccess->mem_size = system->physmem->size(); 809411Sandreas.hansson@arm.com alphaAccess->cpuClock = cpu->getFreq() / 1000000; 819411Sandreas.hansson@arm.com TsunamiIO *clock_linux = dynamic_cast<TsunamiIO *>(clock); 829411Sandreas.hansson@arm.com TlaserClock *clock_tru64 = dynamic_cast<TlaserClock *>(clock); 839411Sandreas.hansson@arm.com if (clock_linux) 849411Sandreas.hansson@arm.com alphaAccess->intrClockFrequency = clock_linux->frequency(); 859411Sandreas.hansson@arm.com else if (clock_tru64) 869235Sandreas.hansson@arm.com alphaAccess->intrClockFrequency = clock_tru64->frequency(); 879235Sandreas.hansson@arm.com else 889235Sandreas.hansson@arm.com panic("clock must be of type TlaserClock or TsunamiIO\n"); 899411Sandreas.hansson@arm.com alphaAccess->diskUnit = 1; 909411Sandreas.hansson@arm.com} 919235Sandreas.hansson@arm.com 929235Sandreas.hansson@arm.comFault 939405Sandreas.hansson@arm.comAlphaConsole::read(MemReqPtr &req, uint8_t *data) 949412Sandreas.hansson@arm.com{ 959412Sandreas.hansson@arm.com memset(data, 0, req->size); 969412Sandreas.hansson@arm.com 979412Sandreas.hansson@arm.com Addr daddr = req->paddr - (addr & PA_IMPL_MASK); 989412Sandreas.hansson@arm.com 999412Sandreas.hansson@arm.com switch (req->size) 1009412Sandreas.hansson@arm.com { 1019412Sandreas.hansson@arm.com case sizeof(uint32_t): 1029412Sandreas.hansson@arm.com DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *(uint32_t*)data); 1039412Sandreas.hansson@arm.com switch (daddr) 1049412Sandreas.hansson@arm.com { 1059412Sandreas.hansson@arm.com case offsetof(AlphaAccess, last_offset): 1069412Sandreas.hansson@arm.com *(uint32_t*)data = alphaAccess->last_offset; 1079412Sandreas.hansson@arm.com break; 1089412Sandreas.hansson@arm.com case offsetof(AlphaAccess, version): 1099412Sandreas.hansson@arm.com *(uint32_t*)data = alphaAccess->version; 1109412Sandreas.hansson@arm.com break; 1119412Sandreas.hansson@arm.com case offsetof(AlphaAccess, numCPUs): 1129412Sandreas.hansson@arm.com *(uint32_t*)data = alphaAccess->numCPUs; 1139412Sandreas.hansson@arm.com break; 1149412Sandreas.hansson@arm.com case offsetof(AlphaAccess, bootStrapCPU): 1159412Sandreas.hansson@arm.com *(uint32_t*)data = alphaAccess->bootStrapCPU; 1169412Sandreas.hansson@arm.com break; 1179412Sandreas.hansson@arm.com case offsetof(AlphaAccess, intrClockFrequency): 1189412Sandreas.hansson@arm.com *(uint32_t*)data = alphaAccess->intrClockFrequency; 1199412Sandreas.hansson@arm.com break; 1209412Sandreas.hansson@arm.com default: 1219412Sandreas.hansson@arm.com panic("Unknown 32bit access, %#x\n", daddr); 1229412Sandreas.hansson@arm.com } 1239412Sandreas.hansson@arm.com break; 1249412Sandreas.hansson@arm.com case sizeof(uint64_t): 1259412Sandreas.hansson@arm.com DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *(uint64_t*)data); 1269412Sandreas.hansson@arm.com switch (daddr) 1279412Sandreas.hansson@arm.com { 1289412Sandreas.hansson@arm.com case offsetof(AlphaAccess, inputChar): 1299412Sandreas.hansson@arm.com *(uint64_t*)data = console->console_in(); 1309412Sandreas.hansson@arm.com break; 1319412Sandreas.hansson@arm.com case offsetof(AlphaAccess, cpuClock): 1329412Sandreas.hansson@arm.com *(uint64_t*)data = alphaAccess->cpuClock; 1339412Sandreas.hansson@arm.com break; 1349411Sandreas.hansson@arm.com case offsetof(AlphaAccess, mem_size): 1359411Sandreas.hansson@arm.com *(uint64_t*)data = alphaAccess->mem_size; 1369411Sandreas.hansson@arm.com break; 1379411Sandreas.hansson@arm.com case offsetof(AlphaAccess, kernStart): 1389411Sandreas.hansson@arm.com *(uint64_t*)data = alphaAccess->kernStart; 1399411Sandreas.hansson@arm.com break; 1409411Sandreas.hansson@arm.com case offsetof(AlphaAccess, kernEnd): 1419411Sandreas.hansson@arm.com *(uint64_t*)data = alphaAccess->kernEnd; 1429411Sandreas.hansson@arm.com break; 1439411Sandreas.hansson@arm.com case offsetof(AlphaAccess, entryPoint): 1449411Sandreas.hansson@arm.com *(uint64_t*)data = alphaAccess->entryPoint; 1459581Sandreas.hansson@arm.com break; 1469581Sandreas.hansson@arm.com case offsetof(AlphaAccess, diskUnit): 1479780Sandreas.hansson@arm.com *(uint64_t*)data = alphaAccess->diskUnit; 1489581Sandreas.hansson@arm.com break; 1499411Sandreas.hansson@arm.com case offsetof(AlphaAccess, diskCount): 1509411Sandreas.hansson@arm.com *(uint64_t*)data = alphaAccess->diskCount; 1519411Sandreas.hansson@arm.com break; 1529411Sandreas.hansson@arm.com case offsetof(AlphaAccess, diskPAddr): 1539411Sandreas.hansson@arm.com *(uint64_t*)data = alphaAccess->diskPAddr; 1549411Sandreas.hansson@arm.com break; 1559411Sandreas.hansson@arm.com case offsetof(AlphaAccess, diskBlock): 1569411Sandreas.hansson@arm.com *(uint64_t*)data = alphaAccess->diskBlock; 1579411Sandreas.hansson@arm.com break; 1589411Sandreas.hansson@arm.com case offsetof(AlphaAccess, diskOperation): 1599405Sandreas.hansson@arm.com *(uint64_t*)data = alphaAccess->diskOperation; 1609411Sandreas.hansson@arm.com break; 1619411Sandreas.hansson@arm.com case offsetof(AlphaAccess, outputChar): 1629405Sandreas.hansson@arm.com *(uint64_t*)data = alphaAccess->outputChar; 1639411Sandreas.hansson@arm.com break; 1649411Sandreas.hansson@arm.com case offsetof(AlphaAccess, bootStrapImpure): 1659411Sandreas.hansson@arm.com *(uint64_t*)data = alphaAccess->bootStrapImpure; 1669411Sandreas.hansson@arm.com break; 167532SN/A default: 1689405Sandreas.hansson@arm.com panic("Unknown 64bit access, %#x\n", daddr); 1699405Sandreas.hansson@arm.com } 1709405Sandreas.hansson@arm.com break; 17110435Snilay@cs.wisc.edu default: 1729405Sandreas.hansson@arm.com return Machine_Check_Fault; 1739405Sandreas.hansson@arm.com } 1749405Sandreas.hansson@arm.com 1759405Sandreas.hansson@arm.com return No_Fault; 1769405Sandreas.hansson@arm.com} 1779405Sandreas.hansson@arm.com 1789405Sandreas.hansson@arm.comFault 1799405Sandreas.hansson@arm.comAlphaConsole::write(MemReqPtr &req, const uint8_t *data) 1809405Sandreas.hansson@arm.com{ 1819405Sandreas.hansson@arm.com uint64_t val; 1829405Sandreas.hansson@arm.com 1839405Sandreas.hansson@arm.com switch (req->size) { 1849405Sandreas.hansson@arm.com case sizeof(uint32_t): 1859411Sandreas.hansson@arm.com val = *(uint32_t *)data; 1869411Sandreas.hansson@arm.com break; 1879411Sandreas.hansson@arm.com 1889411Sandreas.hansson@arm.com case sizeof(uint64_t): 1899411Sandreas.hansson@arm.com val = *(uint64_t *)data; 1909411Sandreas.hansson@arm.com break; 1919411Sandreas.hansson@arm.com default: 1929411Sandreas.hansson@arm.com return Machine_Check_Fault; 1939411Sandreas.hansson@arm.com } 1949411Sandreas.hansson@arm.com 1959411Sandreas.hansson@arm.com Addr daddr = req->paddr - (addr & PA_IMPL_MASK); 1969411Sandreas.hansson@arm.com ExecContext *other_xc; 1979411Sandreas.hansson@arm.com 1989411Sandreas.hansson@arm.com switch (daddr) { 1999411Sandreas.hansson@arm.com case offsetof(AlphaAccess, diskUnit): 2009411Sandreas.hansson@arm.com alphaAccess->diskUnit = val; 2019411Sandreas.hansson@arm.com break; 2029411Sandreas.hansson@arm.com 2039411Sandreas.hansson@arm.com case offsetof(AlphaAccess, diskCount): 2049411Sandreas.hansson@arm.com alphaAccess->diskCount = val; 2059411Sandreas.hansson@arm.com break; 2069405Sandreas.hansson@arm.com 2079279Sandreas.hansson@arm.com case offsetof(AlphaAccess, diskPAddr): 2089279Sandreas.hansson@arm.com alphaAccess->diskPAddr = val; 2099279Sandreas.hansson@arm.com break; 2109279Sandreas.hansson@arm.com 2119279Sandreas.hansson@arm.com case offsetof(AlphaAccess, diskBlock): 2129279Sandreas.hansson@arm.com alphaAccess->diskBlock = val; 2139279Sandreas.hansson@arm.com break; 2149279Sandreas.hansson@arm.com 2159279Sandreas.hansson@arm.com case offsetof(AlphaAccess, diskOperation): 2169279Sandreas.hansson@arm.com if (val == 0x13) 2179279Sandreas.hansson@arm.com disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock, 2189411Sandreas.hansson@arm.com alphaAccess->diskCount); 2199411Sandreas.hansson@arm.com else 2209411Sandreas.hansson@arm.com panic("Invalid disk operation!"); 2219411Sandreas.hansson@arm.com 2229411Sandreas.hansson@arm.com break; 2239411Sandreas.hansson@arm.com 2249411Sandreas.hansson@arm.com case offsetof(AlphaAccess, outputChar): 2259411Sandreas.hansson@arm.com console->out((char)(val & 0xff), false); 2269411Sandreas.hansson@arm.com break; 2279411Sandreas.hansson@arm.com 2289411Sandreas.hansson@arm.com case offsetof(AlphaAccess, bootStrapImpure): 2299411Sandreas.hansson@arm.com alphaAccess->bootStrapImpure = val; 2309411Sandreas.hansson@arm.com break; 2319411Sandreas.hansson@arm.com 2329411Sandreas.hansson@arm.com case offsetof(AlphaAccess, bootStrapCPU): 2339411Sandreas.hansson@arm.com warn("%d: Trying to launch another CPU!", curTick); 2349411Sandreas.hansson@arm.com assert(val > 0 && "Must not access primary cpu"); 2359411Sandreas.hansson@arm.com 2369411Sandreas.hansson@arm.com other_xc = req->xc->system->execContexts[val]; 2379411Sandreas.hansson@arm.com other_xc->regs.intRegFile[16] = val; 2389279Sandreas.hansson@arm.com other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val; 2399279Sandreas.hansson@arm.com other_xc->regs.intRegFile[0] = val; 2409279Sandreas.hansson@arm.com other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure; 2419279Sandreas.hansson@arm.com other_xc->activate(); //Start the cpu 2429279Sandreas.hansson@arm.com break; 2439279Sandreas.hansson@arm.com 2449279Sandreas.hansson@arm.com default: 2459279Sandreas.hansson@arm.com return Machine_Check_Fault; 2469279Sandreas.hansson@arm.com } 2479279Sandreas.hansson@arm.com 2489279Sandreas.hansson@arm.com return No_Fault; 2499279Sandreas.hansson@arm.com} 2509411Sandreas.hansson@arm.com 2519411Sandreas.hansson@arm.comTick 2529405Sandreas.hansson@arm.comAlphaConsole::cacheAccess(MemReqPtr &req) 2539279Sandreas.hansson@arm.com{ 2549405Sandreas.hansson@arm.com return curTick + 1000; 2559405Sandreas.hansson@arm.com} 2569405Sandreas.hansson@arm.com 2579405Sandreas.hansson@arm.comvoid 2589405Sandreas.hansson@arm.comAlphaAccess::serialize(ostream &os) 2599405Sandreas.hansson@arm.com{ 2609405Sandreas.hansson@arm.com SERIALIZE_SCALAR(last_offset); 2619405Sandreas.hansson@arm.com SERIALIZE_SCALAR(version); 2629405Sandreas.hansson@arm.com SERIALIZE_SCALAR(numCPUs); 2639411Sandreas.hansson@arm.com SERIALIZE_SCALAR(mem_size); 2649411Sandreas.hansson@arm.com SERIALIZE_SCALAR(cpuClock); 2659411Sandreas.hansson@arm.com SERIALIZE_SCALAR(intrClockFrequency); 2669411Sandreas.hansson@arm.com SERIALIZE_SCALAR(kernStart); 2679541Sandreas.hansson@arm.com SERIALIZE_SCALAR(kernEnd); 2689411Sandreas.hansson@arm.com SERIALIZE_SCALAR(entryPoint); 2699411Sandreas.hansson@arm.com SERIALIZE_SCALAR(diskUnit); 2709405Sandreas.hansson@arm.com SERIALIZE_SCALAR(diskCount); 2712SN/A SERIALIZE_SCALAR(diskPAddr); 272531SN/A SERIALIZE_SCALAR(diskBlock); 2739235Sandreas.hansson@arm.com SERIALIZE_SCALAR(diskOperation); 274531SN/A SERIALIZE_SCALAR(outputChar); 2759235Sandreas.hansson@arm.com SERIALIZE_SCALAR(inputChar); 2762SN/A SERIALIZE_SCALAR(bootStrapImpure); 2779405Sandreas.hansson@arm.com SERIALIZE_SCALAR(bootStrapCPU); 2789405Sandreas.hansson@arm.com} 2799405Sandreas.hansson@arm.com 2809405Sandreas.hansson@arm.comvoid 2819405Sandreas.hansson@arm.comAlphaAccess::unserialize(Checkpoint *cp, const std::string §ion) 2829405Sandreas.hansson@arm.com{ 2839405Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(last_offset); 2849405Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(version); 2859405Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(numCPUs); 2869411Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(mem_size); 2879411Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(cpuClock); 2889411Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(intrClockFrequency); 2899411Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(kernStart); 2909411Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(kernEnd); 2919411Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(entryPoint); 2929405Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(diskUnit); 293531SN/A UNSERIALIZE_SCALAR(diskCount); 2949405Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(diskPAddr); 2959405Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(diskBlock); 2962SN/A UNSERIALIZE_SCALAR(diskOperation); 29710481Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(outputChar); 29810481Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(inputChar); 29910481Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(bootStrapImpure); 30010481Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(bootStrapCPU); 30110481Sandreas.hansson@arm.com} 3029235Sandreas.hansson@arm.com 3039235Sandreas.hansson@arm.comvoid 3049405Sandreas.hansson@arm.comAlphaConsole::serialize(ostream &os) 3052SN/A{ 3069235Sandreas.hansson@arm.com alphaAccess->serialize(os); 3079235Sandreas.hansson@arm.com} 3089405Sandreas.hansson@arm.com 3092SN/Avoid 3109235Sandreas.hansson@arm.comAlphaConsole::unserialize(Checkpoint *cp, const std::string §ion) 3119235Sandreas.hansson@arm.com{ 3129405Sandreas.hansson@arm.com alphaAccess->unserialize(cp, section); 3132SN/A} 3149235Sandreas.hansson@arm.com 315BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) 316 317 SimObjectParam<SimConsole *> sim_console; 318 SimObjectParam<SimpleDisk *> disk; 319 Param<int> num_cpus; 320 SimObjectParam<MemoryController *> mmu; 321 Param<Addr> addr; 322 SimObjectParam<System *> system; 323 SimObjectParam<BaseCPU *> cpu; 324 SimObjectParam<SimObject *> clock; 325 SimObjectParam<Bus*> io_bus; 326 SimObjectParam<HierParams *> hier; 327 328END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) 329 330BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole) 331 332 INIT_PARAM(sim_console, "The Simulator Console"), 333 INIT_PARAM(disk, "Simple Disk"), 334 INIT_PARAM_DFLT(num_cpus, "Number of CPU's", 1), 335 INIT_PARAM(mmu, "Memory Controller"), 336 INIT_PARAM(addr, "Device Address"), 337 INIT_PARAM(system, "system object"), 338 INIT_PARAM(cpu, "Processor"), 339 INIT_PARAM(clock, "Clock"), 340 INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL), 341 INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) 342 343END_INIT_SIM_OBJECT_PARAMS(AlphaConsole) 344 345CREATE_SIM_OBJECT(AlphaConsole) 346{ 347 return new AlphaConsole(getInstanceName(), sim_console, disk, 348 system, cpu, clock, num_cpus, mmu, 349 addr, hier, io_bus); 350} 351 352REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole) 353