From 2939a7089ad89e38b24f96143dbd3c4292ac0287 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Feb 2006 00:16:44 -0500 Subject: [PATCH] byte_swap.hh was removed from arch/alpha/, and replaced by sim/byteswap.hh. The new file uses LittleEndianGuest and BigEndianGuest namespaces to allow selecting the appropriate functions. arch/alpha/alpha_linux_process.cc: arch/alpha/alpha_tru64_process.cc: Added the endianness namespace. This may change. cpu/exec_context.hh: Changed the include path for byteswap, and forced LittleEndianness for lack of a better solution. cpu/o3/alpha_cpu.hh: Forced LittleEndianness, for lack of a better solution. cpu/o3/alpha_cpu_impl.hh: Cleared away some commented out code. cpu/o3/fetch_impl.hh: Changed the include patch for byteswap, and forced LittleEndianness for lack of a better solution. cpu/simple/cpu.cc: Added an include for byteswap.hh, and fixed the SimpleCPU to LittleEndian. This cpu only does alpha, so that's fine. dev/disk_image.cc: Changed the include path of byteswap.hh kern/freebsd/freebsd_system.cc: kern/linux/linux_system.cc: Added an include for byteswap.hh, and forced LittleEndianness for lack of a better solution. sim/system.cc: Forced LittleEndianness for lack of a better solution. --HG-- extra : convert_revision : b95d3e1265a825e04bd77622a3ac09fbac6bd206 --- arch/alpha/alpha_linux_process.cc | 3 + arch/alpha/alpha_tru64_process.cc | 3 + cpu/exec_context.hh | 6 +- cpu/o3/alpha_cpu.hh | 4 +- cpu/o3/alpha_cpu_impl.hh | 3 - cpu/o3/fetch_impl.hh | 4 +- cpu/simple/cpu.cc | 3 + dev/disk_image.cc | 2 +- kern/freebsd/freebsd_system.cc | 5 +- kern/linux/linux_system.cc | 3 +- sim/byteswap.hh | 141 ++++++++++++++++++++++++++++++ sim/system.cc | 6 +- 12 files changed, 166 insertions(+), 17 deletions(-) create mode 100644 sim/byteswap.hh diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index 83b0b5e5a..16cbf3841 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -26,6 +26,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +namespace LittleEndian {} +using namespace LittleEndian; + #include #include #include // for host open() flags diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index b7a1c7d59..d57054dfd 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -26,6 +26,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +namespace LittleEndian {} +using namespace LittleEndian; + #include #include #if defined(__OpenBSD__) diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 6f38a6960..2bde053b2 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -34,7 +34,7 @@ #include "mem/mem_req.hh" #include "sim/host.hh" #include "sim/serialize.hh" -#include "targetarch/byte_swap.hh" +#include "sim/byteswap.hh" // forward declaration: see functional_memory.hh class FunctionalMemory; @@ -269,7 +269,7 @@ class ExecContext Fault error; error = mem->read(req, data); - data = gtoh(data); + data = LittleEndianGuest::gtoh(data); return error; } @@ -319,7 +319,7 @@ class ExecContext } #endif - return mem->write(req, (T)htog(data)); + return mem->write(req, (T)LittleEndianGuest::htog(data)); } virtual bool misspeculating(); diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index cba57d189..164da4968 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -220,7 +220,7 @@ class AlphaFullCPU : public FullO3CPU Fault error; error = this->mem->read(req, data); - data = gtoh(data); + data = LittleEndianGuest::gtoh(data); return error; } @@ -277,7 +277,7 @@ class AlphaFullCPU : public FullO3CPU #endif - return this->mem->write(req, (T)htog(data)); + return this->mem->write(req, (T)LittleEndianGuest::htog(data)); } template diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index 2a764740b..3b16975a9 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -42,9 +42,6 @@ #if FULL_SYSTEM #include "arch/alpha/osfpal.hh" #include "arch/alpha/isa_traits.hh" -//#include "arch/alpha/ev5.hh" - -//using namespace EV5; #endif template diff --git a/cpu/o3/fetch_impl.hh b/cpu/o3/fetch_impl.hh index c943fd36a..1a8411cc1 100644 --- a/cpu/o3/fetch_impl.hh +++ b/cpu/o3/fetch_impl.hh @@ -30,7 +30,7 @@ #define OPCODE(X) (X >> 26) & 0x3f -#include "arch/alpha/byte_swap.hh" +#include "sim/byteswap.hh" #include "cpu/exetrace.hh" #include "mem/base_mem.hh" #include "mem/mem_interface.hh" @@ -535,7 +535,7 @@ SimpleFetch::fetch() assert(offset <= cacheBlkSize - instSize); // Get the instruction from the array of the cache line. - inst = gtoh(*reinterpret_cast + inst = LittleEndianGuest::gtoh(*reinterpret_cast (&cacheData[offset])); // Create a new DynInst from the instruction fetched. diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index a7f4fa499..70217f0bb 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -54,6 +54,7 @@ #include "kern/kernel_stats.hh" #include "mem/base_mem.hh" #include "mem/mem_interface.hh" +#include "sim/byteswap.hh" #include "sim/builder.hh" #include "sim/debug.hh" #include "sim/host.hh" @@ -74,6 +75,8 @@ #endif // FULL_SYSTEM using namespace std; +//The SimpleCPU does alpha only +using namespace LittleEndianGuest; SimpleCPU::TickEvent::TickEvent(SimpleCPU *c, int w) diff --git a/dev/disk_image.cc b/dev/disk_image.cc index 106723c55..447c54697 100644 --- a/dev/disk_image.cc +++ b/dev/disk_image.cc @@ -46,7 +46,7 @@ #include "dev/disk_image.hh" #include "sim/builder.hh" #include "sim/sim_exit.hh" -#include "targetarch/byte_swap.hh" +#include "sim/byteswap.hh" using namespace std; diff --git a/kern/freebsd/freebsd_system.cc b/kern/freebsd/freebsd_system.cc index 283713d40..f3fe84e00 100644 --- a/kern/freebsd/freebsd_system.cc +++ b/kern/freebsd/freebsd_system.cc @@ -39,6 +39,7 @@ #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/builder.hh" +#include "sim/byteswap.hh" #include "targetarch/vtophys.hh" #define TIMER_FREQUENCY 1193180 @@ -82,8 +83,8 @@ FreebsdSystem::doCalibrateClocks(ExecContext *xc) uint8_t *ppc = physmem->dma_addr(ppc_paddr, sizeof(uint32_t)); uint8_t *timer = physmem->dma_addr(timer_paddr, sizeof(uint32_t)); - *(uint32_t *)ppc = htog((uint32_t)Clock::Frequency); - *(uint32_t *)timer = htog((uint32_t)TIMER_FREQUENCY); + *(uint32_t *)ppc = LittleEndianGuest::htog((uint32_t)Clock::Frequency); + *(uint32_t *)timer = LittleEndianGuest::htog((uint32_t)TIMER_FREQUENCY); } diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index 1144b9bdd..26a4c0d3e 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -44,6 +44,7 @@ #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/builder.hh" +#include "sim/byteswap.hh" #include "dev/platform.hh" #include "targetarch/arguments.hh" #include "targetarch/vtophys.hh" @@ -100,7 +101,7 @@ LinuxSystem::LinuxSystem(Params *p) char *dp264_mv = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); if (dp264_mv) { - *(uint32_t*)(dp264_mv+0x18) = htog((uint32_t)127); + *(uint32_t*)(dp264_mv+0x18) = LittleEndianGuest::htog((uint32_t)127); } else panic("could not translate dp264_mv addr\n"); diff --git a/sim/byteswap.hh b/sim/byteswap.hh new file mode 100644 index 000000000..12d63b6b6 --- /dev/null +++ b/sim/byteswap.hh @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2004 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//The purpose of this file is to provide endainness conversion utility +//functions. Depending on the endianness of the guest system, either +//the LittleEndianGuest or BigEndianGuest namespace is used. + +#ifndef __SIM_BYTE_SWAP_HH__ +#define __SIM_BYTE_SWAP_HH__ + +#include "sim/host.hh" + +// This lets us figure out what the byte order of the host system is +#if defined(linux) +#include +#else +#include +#endif + +//These functions actually perform the swapping for parameters +//of various bit lengths +static inline uint64_t +swap_byte64(uint64_t x) +{ + return (uint64_t)((((uint64_t)(x) & 0xff) << 56) | + ((uint64_t)(x) & 0xff00ULL) << 40 | + ((uint64_t)(x) & 0xff0000ULL) << 24 | + ((uint64_t)(x) & 0xff000000ULL) << 8 | + ((uint64_t)(x) & 0xff00000000ULL) >> 8 | + ((uint64_t)(x) & 0xff0000000000ULL) >> 24 | + ((uint64_t)(x) & 0xff000000000000ULL) >> 40 | + ((uint64_t)(x) & 0xff00000000000000ULL) >> 56) ; +} + +static inline uint32_t +swap_byte32(uint32_t x) +{ + return (uint32_t)(((uint32_t)(x) & 0xff) << 24 | + ((uint32_t)(x) & 0xff00) << 8 | ((uint32_t)(x) & 0xff0000) >> 8 | + ((uint32_t)(x) & 0xff000000) >> 24); + +} + +static inline uint16_t +swap_byte16(uint16_t x) +{ + return (uint16_t)(((uint16_t)(x) & 0xff) << 8 | + ((uint16_t)(x) & 0xff00) >> 8); +} + +//This lets the compiler figure out how to call the swap_byte functions above +//for different data types. +static inline uint64_t swap_byte(uint64_t x) {return swap_byte64(x);} \ +static inline int64_t swap_byte(int64_t x) {return swap_byte64((uint64_t)x);} \ +static inline uint32_t swap_byte(uint32_t x) {return swap_byte32(x);} \ +static inline int32_t swap_byte(int32_t x) {return swap_byte32((uint32_t)x);} \ +static inline uint16_t swap_byte(uint16_t x) {return swap_byte32(x);} \ +static inline int16_t swap_byte(int16_t x) {return swap_byte16((uint16_t)x);} \ +static inline uint8_t swap_byte(uint8_t x) {return x;} \ +static inline int8_t swap_byte(int8_t x) {return x;} \ +static inline double swap_byte(double x) {return swap_byte64((uint64_t)x);} \ +static inline float swap_byte(float x) {return swap_byte32((uint32_t)x);} + +//The conversion functions with fixed endianness on both ends don't need to +//be in a namespace +template static inline T betole(T value) {return swap_byte(value);} +template static inline T letobe(T value) {return swap_byte(value);} + +//For conversions not involving the guest system, we can define the functions +//conditionally based on the BYTE_ORDER macro and outside of the namespaces +#if BYTE_ORDER == BIG_ENDIAN +template static inline T htole(T value) {return swap_byte(value);} +template static inline T letoh(T value) {return swap_byte(value);} +template static inline T htobe(T value) {return value;} +template static inline T betoh(T value) {return value;} +#elif BYTE_ORDER == LITTLE_ENDIAN +template static inline T htole(T value) {return value;} +template static inline T letoh(T value) {return value;} +template static inline T htobe(T value) {return swap_byte(value);} +template static inline T betoh(T value) {return swap_byte(value);} +#else + #error Invalid Endianess +#endif + +namespace BigEndianGuest +{ + template + static inline T gtole(T value) {return betole(value);} + template + static inline T letog(T value) {return letobe(value);} + template + static inline T gtobe(T value) {return value;} + template + static inline T betog(T value) {return value;} + template + static inline T htog(T value) {return htobe(value);} + template + static inline T gtoh(T value) {return betoh(value);} +} + +namespace LittleEndianGuest +{ + template + static inline T gtole(T value) {return value;} + template + static inline T letog(T value) {return value;} + template + static inline T gtobe(T value) {return letobe(value);} + template + static inline T betog(T value) {return betole(value);} + template + static inline T htog(T value) {return htole(value);} + template + static inline T gtoh(T value) {return letoh(value);} +} +#endif // __SIM_BYTE_SWAP_HH__ diff --git a/sim/system.cc b/sim/system.cc index 4bcc89c56..a69bf27f1 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -152,8 +152,8 @@ System::System(Params *p) if (!hwrpb) panic("could not translate hwrpb addr\n"); - *(uint64_t*)(hwrpb+0x50) = htog(params->system_type); - *(uint64_t*)(hwrpb+0x58) = htog(params->system_rev); + *(uint64_t*)(hwrpb+0x50) = LittleEndianGuest::htog(params->system_type); + *(uint64_t*)(hwrpb+0x58) = LittleEndianGuest::htog(params->system_rev); } else panic("could not find hwrpb\n"); @@ -249,7 +249,7 @@ System::setAlphaAccess(Addr access) if (!m5AlphaAccess) panic("could not translate m5AlphaAccess addr\n"); - *m5AlphaAccess = htog(EV5::Phys2K0Seg(access)); + *m5AlphaAccess = LittleEndianGuest::htog(EV5::Phys2K0Seg(access)); } else panic("could not find m5AlphaAccess\n"); } -- 2.30.2