diff options
-rw-r--r-- | cmake/arm.cmake | 9 | ||||
-rw-r--r-- | include/APE_SHM.h | 128 | ||||
-rw-r--r-- | include/bcm5719_SHM.h | 128 | ||||
-rw-r--r-- | ipxact/SHM.xml | 73 | ||||
-rw-r--r-- | simulator/bcm5719_SHM.cpp | 8 | ||||
-rw-r--r-- | simulator/bcm5719_SHM_mmap.cpp | 20 | ||||
-rw-r--r-- | utils/bcmregtool/CMakeLists.txt | 5 | ||||
-rw-r--r-- | utils/bcmregtool/apeloader/CMakeLists.txt | 66 | ||||
-rw-r--r-- | utils/bcmregtool/apeloader/ape.h | 66 | ||||
-rw-r--r-- | utils/bcmregtool/apeloader/ape.ld | 46 | ||||
-rw-r--r-- | utils/bcmregtool/apeloader/main.c | 95 | ||||
-rw-r--r-- | utils/bcmregtool/main.cpp | 152 |
12 files changed, 780 insertions, 16 deletions
diff --git a/cmake/arm.cmake b/cmake/arm.cmake index c63eea5..b27e1cf 100644 --- a/cmake/arm.cmake +++ b/cmake/arm.cmake @@ -65,6 +65,15 @@ function(arm_add_executable target) COMMAND elf2ape -i ${target} -o ${target}.bin BYPRODUCTS ${target}.bin DEPENDS elf2ape) + + add_custom_command( + OUTPUT ${target}.c + COMMAND xxd -i ${target}.bin ${target}.c + DEPENDS ${target} + VERBATIM) + + # Add host binary + add_library(${target}-binary EXCLUDE_FROM_ALL ${target}.c) endfunction(arm_add_executable) # ARM-specific libraries diff --git a/include/APE_SHM.h b/include/APE_SHM.h index 5baa755..a59e79b 100644 --- a/include/APE_SHM.h +++ b/include/APE_SHM.h @@ -82,12 +82,58 @@ typedef uint32_t APE_SHM_H_uint32_t; #define REG_SHM_SIZE (sizeof(SHM_t)) #define REG_SHM_SEG_SIG ((volatile APE_SHM_H_uint32_t*)0x60220000) /* APE_APE_MAGIC ('APE!') when all is well. */ +#define SHM_SEG_SIG_SIG_SHIFT 0u +#define SHM_SEG_SIG_SIG_MASK 0xffffffffu +#define GET_SHM_SEG_SIG_SIG(__reg__) (((__reg__) & 0xffffffff) >> 0u) +#define SET_SHM_SEG_SIG_SIG(__val__) (((__val__) << 0u) & 0xffffffffu) +#define SHM_SEG_SIG_SIG_LOADER 0x10ad10adu + + /** @brief Register definition for @ref SHM_t.SegSig. */ typedef register_container RegSHMSegSig_t { /** @brief 32bit direct register access. */ APE_SHM_H_uint32_t r32; + + BITFIELD_BEGIN(APE_SHM_H_uint32_t, bits) +#if defined(__LITTLE_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(APE_SHM_H_uint32_t, Sig, 0, 32) +#elif defined(__BIG_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(APE_SHM_H_uint32_t, Sig, 0, 32) +#else +#error Unknown Endian +#endif + BITFIELD_END(APE_SHM_H_uint32_t, bits) +#ifdef CXX_SIMULATOR + /** @brief Register name for use with the simulator. */ + const char* getName(void) { return "SegSig"; } + + /** @brief Print register value. */ + void print(void) { r32.print(); } + + RegSHMSegSig_t() + { + /** @brief constructor for @ref SHM_t.SegSig. */ + r32.setName("SegSig"); + bits.Sig.setBaseRegister(&r32); + bits.Sig.setName("Sig"); + } + RegSHMSegSig_t& operator=(const RegSHMSegSig_t& other) + { + r32 = other.r32; + return *this; + } +#endif /* CXX_SIMULATOR */ } RegSHMSegSig_t; +#define REG_SHM_APE_SEG_LENGTH ((volatile APE_SHM_H_uint32_t*)0x60220004) /* Set to 0x34. */ +/** @brief Register definition for @ref SHM_t.ApeSegLength. */ +typedef register_container RegSHMApeSegLength_t { + /** @brief 32bit direct register access. */ + APE_SHM_H_uint32_t r32; +} RegSHMApeSegLength_t; + #define REG_SHM_FW_STATUS ((volatile APE_SHM_H_uint32_t*)0x6022000c) /* */ #define SHM_FW_STATUS_READY_SHIFT 8u #define SHM_FW_STATUS_READY_MASK 0x100u @@ -311,6 +357,69 @@ typedef register_container RegSHM4028_t { APE_SHM_H_uint32_t r32; } RegSHM4028_t; +#define REG_SHM_LOADER_COMMAND ((volatile APE_SHM_H_uint32_t*)0x60220038) /* Command sent when using the the APE loader. Zero once handled. */ +#define SHM_LOADER_COMMAND_COMMAND_SHIFT 0u +#define SHM_LOADER_COMMAND_COMMAND_MASK 0xffffffffu +#define GET_SHM_LOADER_COMMAND_COMMAND(__reg__) (((__reg__) & 0xffffffff) >> 0u) +#define SET_SHM_LOADER_COMMAND_COMMAND(__val__) (((__val__) << 0u) & 0xffffffffu) +#define SHM_LOADER_COMMAND_COMMAND_NOP 0x0u +#define SHM_LOADER_COMMAND_COMMAND_READ_MEM 0x1u +#define SHM_LOADER_COMMAND_COMMAND_WRITE_MEM 0x2u +#define SHM_LOADER_COMMAND_COMMAND_CALL 0x3u + + +/** @brief Register definition for @ref SHM_t.LoaderCommand. */ +typedef register_container RegSHMLoaderCommand_t { + /** @brief 32bit direct register access. */ + APE_SHM_H_uint32_t r32; + + BITFIELD_BEGIN(APE_SHM_H_uint32_t, bits) +#if defined(__LITTLE_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(APE_SHM_H_uint32_t, Command, 0, 32) +#elif defined(__BIG_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(APE_SHM_H_uint32_t, Command, 0, 32) +#else +#error Unknown Endian +#endif + BITFIELD_END(APE_SHM_H_uint32_t, bits) +#ifdef CXX_SIMULATOR + /** @brief Register name for use with the simulator. */ + const char* getName(void) { return "LoaderCommand"; } + + /** @brief Print register value. */ + void print(void) { r32.print(); } + + RegSHMLoaderCommand_t() + { + /** @brief constructor for @ref SHM_t.LoaderCommand. */ + r32.setName("LoaderCommand"); + bits.Command.setBaseRegister(&r32); + bits.Command.setName("Command"); + } + RegSHMLoaderCommand_t& operator=(const RegSHMLoaderCommand_t& other) + { + r32 = other.r32; + return *this; + } +#endif /* CXX_SIMULATOR */ +} RegSHMLoaderCommand_t; + +#define REG_SHM_LOADER_ARG0 ((volatile APE_SHM_H_uint32_t*)0x6022003c) /* Argument 0 for the APE loader. */ +/** @brief Register definition for @ref SHM_t.LoaderArg0. */ +typedef register_container RegSHMLoaderArg0_t { + /** @brief 32bit direct register access. */ + APE_SHM_H_uint32_t r32; +} RegSHMLoaderArg0_t; + +#define REG_SHM_LOADER_ARG1 ((volatile APE_SHM_H_uint32_t*)0x60220040) /* Argument 1 for the APE loader. */ +/** @brief Register definition for @ref SHM_t.LoaderArg1. */ +typedef register_container RegSHMLoaderArg1_t { + /** @brief 32bit direct register access. */ + APE_SHM_H_uint32_t r32; +} RegSHMLoaderArg1_t; + #define REG_SHM_RCPU_SEG_SIG ((volatile APE_SHM_H_uint32_t*)0x60220100) /* Set to APE_RCPU_MAGIC ('RCPU') by RX CPU. */ #define SHM_RCPU_SEG_SIG_SIG_SHIFT 0u #define SHM_RCPU_SEG_SIG_SIG_MASK 0xffffffffu @@ -1605,8 +1714,11 @@ typedef struct { /** @brief APE_APE_MAGIC ('APE!') when all is well. */ RegSHMSegSig_t SegSig; + /** @brief Set to 0x34. */ + RegSHMApeSegLength_t ApeSegLength; + /** @brief Reserved bytes to pad out data structure. */ - APE_SHM_H_uint32_t reserved_4[2]; + APE_SHM_H_uint32_t reserved_8[1]; /** @brief */ RegSHMFwStatus_t FwStatus; @@ -1633,7 +1745,19 @@ typedef struct { RegSHM4028_t _4028; /** @brief Reserved bytes to pad out data structure. */ - APE_SHM_H_uint32_t reserved_44[53]; + APE_SHM_H_uint32_t reserved_44[3]; + + /** @brief Command sent when using the the APE loader. Zero once handled. */ + RegSHMLoaderCommand_t LoaderCommand; + + /** @brief Argument 0 for the APE loader. */ + RegSHMLoaderArg0_t LoaderArg0; + + /** @brief Argument 1 for the APE loader. */ + RegSHMLoaderArg1_t LoaderArg1; + + /** @brief Reserved bytes to pad out data structure. */ + APE_SHM_H_uint32_t reserved_68[47]; /** @brief Set to APE_RCPU_MAGIC ('RCPU') by RX CPU. */ RegSHMRcpuSegSig_t RcpuSegSig; diff --git a/include/bcm5719_SHM.h b/include/bcm5719_SHM.h index 8394c82..d1b5d7b 100644 --- a/include/bcm5719_SHM.h +++ b/include/bcm5719_SHM.h @@ -82,12 +82,58 @@ typedef uint32_t BCM5719_SHM_H_uint32_t; #define REG_SHM_SIZE (sizeof(SHM_t)) #define REG_SHM_SEG_SIG ((volatile BCM5719_SHM_H_uint32_t*)0xc0014000) /* APE_APE_MAGIC ('APE!') when all is well. */ +#define SHM_SEG_SIG_SIG_SHIFT 0u +#define SHM_SEG_SIG_SIG_MASK 0xffffffffu +#define GET_SHM_SEG_SIG_SIG(__reg__) (((__reg__) & 0xffffffff) >> 0u) +#define SET_SHM_SEG_SIG_SIG(__val__) (((__val__) << 0u) & 0xffffffffu) +#define SHM_SEG_SIG_SIG_LOADER 0x10ad10adu + + /** @brief Register definition for @ref SHM_t.SegSig. */ typedef register_container RegSHMSegSig_t { /** @brief 32bit direct register access. */ BCM5719_SHM_H_uint32_t r32; + + BITFIELD_BEGIN(BCM5719_SHM_H_uint32_t, bits) +#if defined(__LITTLE_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(BCM5719_SHM_H_uint32_t, Sig, 0, 32) +#elif defined(__BIG_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(BCM5719_SHM_H_uint32_t, Sig, 0, 32) +#else +#error Unknown Endian +#endif + BITFIELD_END(BCM5719_SHM_H_uint32_t, bits) +#ifdef CXX_SIMULATOR + /** @brief Register name for use with the simulator. */ + const char* getName(void) { return "SegSig"; } + + /** @brief Print register value. */ + void print(void) { r32.print(); } + + RegSHMSegSig_t() + { + /** @brief constructor for @ref SHM_t.SegSig. */ + r32.setName("SegSig"); + bits.Sig.setBaseRegister(&r32); + bits.Sig.setName("Sig"); + } + RegSHMSegSig_t& operator=(const RegSHMSegSig_t& other) + { + r32 = other.r32; + return *this; + } +#endif /* CXX_SIMULATOR */ } RegSHMSegSig_t; +#define REG_SHM_APE_SEG_LENGTH ((volatile BCM5719_SHM_H_uint32_t*)0xc0014004) /* Set to 0x34. */ +/** @brief Register definition for @ref SHM_t.ApeSegLength. */ +typedef register_container RegSHMApeSegLength_t { + /** @brief 32bit direct register access. */ + BCM5719_SHM_H_uint32_t r32; +} RegSHMApeSegLength_t; + #define REG_SHM_FW_STATUS ((volatile BCM5719_SHM_H_uint32_t*)0xc001400c) /* */ #define SHM_FW_STATUS_READY_SHIFT 8u #define SHM_FW_STATUS_READY_MASK 0x100u @@ -311,6 +357,69 @@ typedef register_container RegSHM4028_t { BCM5719_SHM_H_uint32_t r32; } RegSHM4028_t; +#define REG_SHM_LOADER_COMMAND ((volatile BCM5719_SHM_H_uint32_t*)0xc0014038) /* Command sent when using the the APE loader. Zero once handled. */ +#define SHM_LOADER_COMMAND_COMMAND_SHIFT 0u +#define SHM_LOADER_COMMAND_COMMAND_MASK 0xffffffffu +#define GET_SHM_LOADER_COMMAND_COMMAND(__reg__) (((__reg__) & 0xffffffff) >> 0u) +#define SET_SHM_LOADER_COMMAND_COMMAND(__val__) (((__val__) << 0u) & 0xffffffffu) +#define SHM_LOADER_COMMAND_COMMAND_NOP 0x0u +#define SHM_LOADER_COMMAND_COMMAND_READ_MEM 0x1u +#define SHM_LOADER_COMMAND_COMMAND_WRITE_MEM 0x2u +#define SHM_LOADER_COMMAND_COMMAND_CALL 0x3u + + +/** @brief Register definition for @ref SHM_t.LoaderCommand. */ +typedef register_container RegSHMLoaderCommand_t { + /** @brief 32bit direct register access. */ + BCM5719_SHM_H_uint32_t r32; + + BITFIELD_BEGIN(BCM5719_SHM_H_uint32_t, bits) +#if defined(__LITTLE_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(BCM5719_SHM_H_uint32_t, Command, 0, 32) +#elif defined(__BIG_ENDIAN__) + /** @brief */ + BITFIELD_MEMBER(BCM5719_SHM_H_uint32_t, Command, 0, 32) +#else +#error Unknown Endian +#endif + BITFIELD_END(BCM5719_SHM_H_uint32_t, bits) +#ifdef CXX_SIMULATOR + /** @brief Register name for use with the simulator. */ + const char* getName(void) { return "LoaderCommand"; } + + /** @brief Print register value. */ + void print(void) { r32.print(); } + + RegSHMLoaderCommand_t() + { + /** @brief constructor for @ref SHM_t.LoaderCommand. */ + r32.setName("LoaderCommand"); + bits.Command.setBaseRegister(&r32); + bits.Command.setName("Command"); + } + RegSHMLoaderCommand_t& operator=(const RegSHMLoaderCommand_t& other) + { + r32 = other.r32; + return *this; + } +#endif /* CXX_SIMULATOR */ +} RegSHMLoaderCommand_t; + +#define REG_SHM_LOADER_ARG0 ((volatile BCM5719_SHM_H_uint32_t*)0xc001403c) /* Argument 0 for the APE loader. */ +/** @brief Register definition for @ref SHM_t.LoaderArg0. */ +typedef register_container RegSHMLoaderArg0_t { + /** @brief 32bit direct register access. */ + BCM5719_SHM_H_uint32_t r32; +} RegSHMLoaderArg0_t; + +#define REG_SHM_LOADER_ARG1 ((volatile BCM5719_SHM_H_uint32_t*)0xc0014040) /* Argument 1 for the APE loader. */ +/** @brief Register definition for @ref SHM_t.LoaderArg1. */ +typedef register_container RegSHMLoaderArg1_t { + /** @brief 32bit direct register access. */ + BCM5719_SHM_H_uint32_t r32; +} RegSHMLoaderArg1_t; + #define REG_SHM_RCPU_SEG_SIG ((volatile BCM5719_SHM_H_uint32_t*)0xc0014100) /* Set to APE_RCPU_MAGIC ('RCPU') by RX CPU. */ #define SHM_RCPU_SEG_SIG_SIG_SHIFT 0u #define SHM_RCPU_SEG_SIG_SIG_MASK 0xffffffffu @@ -1605,8 +1714,11 @@ typedef struct { /** @brief APE_APE_MAGIC ('APE!') when all is well. */ RegSHMSegSig_t SegSig; + /** @brief Set to 0x34. */ + RegSHMApeSegLength_t ApeSegLength; + /** @brief Reserved bytes to pad out data structure. */ - BCM5719_SHM_H_uint32_t reserved_4[2]; + BCM5719_SHM_H_uint32_t reserved_8[1]; /** @brief */ RegSHMFwStatus_t FwStatus; @@ -1633,7 +1745,19 @@ typedef struct { RegSHM4028_t _4028; /** @brief Reserved bytes to pad out data structure. */ - BCM5719_SHM_H_uint32_t reserved_44[53]; + BCM5719_SHM_H_uint32_t reserved_44[3]; + + /** @brief Command sent when using the the APE loader. Zero once handled. */ + RegSHMLoaderCommand_t LoaderCommand; + + /** @brief Argument 0 for the APE loader. */ + RegSHMLoaderArg0_t LoaderArg0; + + /** @brief Argument 1 for the APE loader. */ + RegSHMLoaderArg1_t LoaderArg1; + + /** @brief Reserved bytes to pad out data structure. */ + BCM5719_SHM_H_uint32_t reserved_68[47]; /** @brief Set to APE_RCPU_MAGIC ('RCPU') by RX CPU. */ RegSHMRcpuSegSig_t RcpuSegSig; diff --git a/ipxact/SHM.xml b/ipxact/SHM.xml index 52cdc00..b5e9072 100644 --- a/ipxact/SHM.xml +++ b/ipxact/SHM.xml @@ -27,6 +27,28 @@ <!-- LINK: registerDefinitionGroup: see 6.11.3, Register definition group --> <ipxact:size>32</ipxact:size> <ipxact:volatile>true</ipxact:volatile> + <ipxact:field> + <ipxact:name>Sig</ipxact:name> + <ipxact:description></ipxact:description> + <ipxact:bitOffset>0</ipxact:bitOffset> + <ipxact:bitWidth>32</ipxact:bitWidth> + <ipxact:access>read-write</ipxact:access> + <ipxact:enumeratedValues> + <!-- LINK: enumeratedValue: see 6.11.10, Enumeration values --> + <ipxact:enumeratedValue> + <ipxact:name>LOADER</ipxact:name> + <ipxact:value>0x10AD10AD</ipxact:value> + </ipxact:enumeratedValue> + </ipxact:enumeratedValues> + </ipxact:field> + </ipxact:register> + <ipxact:register> + <ipxact:name>APE_SEG_LENGTH</ipxact:name> + <ipxact:description>Set to 0x34.</ipxact:description> + <ipxact:addressOffset>0x4</ipxact:addressOffset> + <!-- LINK: registerDefinitionGroup: see 6.11.3, Register definition group --> + <ipxact:size>32</ipxact:size> + <ipxact:volatile>true</ipxact:volatile> </ipxact:register> <ipxact:register> <ipxact:name>FW_STATUS</ipxact:name> @@ -142,6 +164,57 @@ <ipxact:volatile>true</ipxact:volatile> </ipxact:register> <ipxact:register> + <ipxact:name>Loader_Command</ipxact:name> + <ipxact:description>Command sent when using the the APE loader. Zero once handled.</ipxact:description> + <ipxact:addressOffset>0x38</ipxact:addressOffset> + <!-- LINK: registerDefinitionGroup: see 6.11.3, Register definition group --> + <ipxact:size>32</ipxact:size> + <ipxact:volatile>true</ipxact:volatile> + <ipxact:field> + <ipxact:name>Command</ipxact:name> + <ipxact:description></ipxact:description> + <ipxact:bitOffset>0</ipxact:bitOffset> + <ipxact:bitWidth>32</ipxact:bitWidth> + <ipxact:access>read-write</ipxact:access> + <ipxact:enumeratedValues> + <!-- LINK: enumeratedValue: see 6.11.10, Enumeration values --> + <ipxact:enumeratedValue> + <ipxact:name>NOP</ipxact:name> + <ipxact:value>0</ipxact:value> + </ipxact:enumeratedValue> + <ipxact:enumeratedValue> + <ipxact:name>READ_MEM</ipxact:name> + <ipxact:value>1</ipxact:value> + </ipxact:enumeratedValue> + <ipxact:enumeratedValue> + <ipxact:name>WRITE_MEM</ipxact:name> + <ipxact:value>2</ipxact:value> + </ipxact:enumeratedValue> + <ipxact:enumeratedValue> + <ipxact:name>CALL</ipxact:name> + <ipxact:value>3</ipxact:value> + </ipxact:enumeratedValue> + </ipxact:enumeratedValues> + </ipxact:field> + </ipxact:register> + <ipxact:register> + <ipxact:name>Loader_Arg0</ipxact:name> + <ipxact:description>Argument 0 for the APE loader.</ipxact:description> + <ipxact:addressOffset>0x3c</ipxact:addressOffset> + <!-- LINK: registerDefinitionGroup: see 6.11.3, Register definition group --> + <ipxact:size>32</ipxact:size> + <ipxact:volatile>true</ipxact:volatile> + </ipxact:register> + <ipxact:register> + <ipxact:name>Loader_Arg1</ipxact:name> + <ipxact:description>Argument 1 for the APE loader.</ipxact:description> + <ipxact:addressOffset>0x40</ipxact:addressOffset> + <!-- LINK: registerDefinitionGroup: see 6.11.3, Register definition group --> + <ipxact:size>32</ipxact:size> + <ipxact:volatile>true</ipxact:volatile> + </ipxact:register> + + <ipxact:register> <ipxact:name>RCPU_SEG_SIG</ipxact:name> <ipxact:description>Set to APE_RCPU_MAGIC ('RCPU') by RX CPU.</ipxact:description> <ipxact:addressOffset>0x100</ipxact:addressOffset> diff --git a/simulator/bcm5719_SHM.cpp b/simulator/bcm5719_SHM.cpp index a369dfa..4fd20f7 100644 --- a/simulator/bcm5719_SHM.cpp +++ b/simulator/bcm5719_SHM.cpp @@ -51,6 +51,8 @@ void init_bcm5719_SHM(void) /** @brief Component Registers for @ref SHM. */ /** @brief Bitmap for @ref SHM_t.SegSig. */ + /** @brief Bitmap for @ref SHM_t.ApeSegLength. */ + /** @brief Bitmap for @ref SHM_t.FwStatus. */ /** @brief Bitmap for @ref SHM_t.FwFeatures. */ @@ -67,6 +69,12 @@ void init_bcm5719_SHM(void) /** @brief Bitmap for @ref SHM_t.4028. */ + /** @brief Bitmap for @ref SHM_t.LoaderCommand. */ + + /** @brief Bitmap for @ref SHM_t.LoaderArg0. */ + + /** @brief Bitmap for @ref SHM_t.LoaderArg1. */ + /** @brief Bitmap for @ref SHM_t.RcpuSegSig. */ /** @brief Bitmap for @ref SHM_t.RcpuSegLength. */ diff --git a/simulator/bcm5719_SHM_mmap.cpp b/simulator/bcm5719_SHM_mmap.cpp index bdcea46..772c4e3 100644 --- a/simulator/bcm5719_SHM_mmap.cpp +++ b/simulator/bcm5719_SHM_mmap.cpp @@ -111,6 +111,11 @@ void init_bcm5719_SHM_mmap(void *base) SHM.SegSig.r32.installReadCallback(read_from_ram, &SHM_SegSig_r32); SHM.SegSig.r32.installWriteCallback(write_to_ram, &SHM_SegSig_r32); + /** @brief Bitmap for @ref SHM_t.ApeSegLength. */ + static ram_offset_t SHM_ApeSegLength_r32((uint8_t *)base, (uint32_t)4); + SHM.ApeSegLength.r32.installReadCallback(read_from_ram, &SHM_ApeSegLength_r32); + SHM.ApeSegLength.r32.installWriteCallback(write_to_ram, &SHM_ApeSegLength_r32); + /** @brief Bitmap for @ref SHM_t.FwStatus. */ static ram_offset_t SHM_FwStatus_r32((uint8_t *)base, (uint32_t)12); SHM.FwStatus.r32.installReadCallback(read_from_ram, &SHM_FwStatus_r32); @@ -151,6 +156,21 @@ void init_bcm5719_SHM_mmap(void *base) SHM._4028.r32.installReadCallback(read_from_ram, &SHM__4028_r32); SHM._4028.r32.installWriteCallback(write_to_ram, &SHM__4028_r32); + /** @brief Bitmap for @ref SHM_t.LoaderCommand. */ + static ram_offset_t SHM_LoaderCommand_r32((uint8_t *)base, (uint32_t)56); + SHM.LoaderCommand.r32.installReadCallback(read_from_ram, &SHM_LoaderCommand_r32); + SHM.LoaderCommand.r32.installWriteCallback(write_to_ram, &SHM_LoaderCommand_r32); + + /** @brief Bitmap for @ref SHM_t.LoaderArg0. */ + static ram_offset_t SHM_LoaderArg0_r32((uint8_t *)base, (uint32_t)60); + SHM.LoaderArg0.r32.installReadCallback(read_from_ram, &SHM_LoaderArg0_r32); + SHM.LoaderArg0.r32.installWriteCallback(write_to_ram, &SHM_LoaderArg0_r32); + + /** @brief Bitmap for @ref SHM_t.LoaderArg1. */ + static ram_offset_t SHM_LoaderArg1_r32((uint8_t *)base, (uint32_t)64); + SHM.LoaderArg1.r32.installReadCallback(read_from_ram, &SHM_LoaderArg1_r32); + SHM.LoaderArg1.r32.installWriteCallback(write_to_ram, &SHM_LoaderArg1_r32); + /** @brief Bitmap for @ref SHM_t.RcpuSegSig. */ static ram_offset_t SHM_RcpuSegSig_r32((uint8_t *)base, (uint32_t)256); SHM.RcpuSegSig.r32.installReadCallback(read_from_ram, &SHM_RcpuSegSig_r32); diff --git a/utils/bcmregtool/CMakeLists.txt b/utils/bcmregtool/CMakeLists.txt index e8d3f33..9a2200b 100644 --- a/utils/bcmregtool/CMakeLists.txt +++ b/utils/bcmregtool/CMakeLists.txt @@ -1,12 +1,15 @@ project(bcmregtool) + +add_subdirectory(apeloader) + add_definitions(-Wall -Werror) set(SOURCES main.cpp ) simulator_add_executable(${PROJECT_NAME} ${SOURCES}) -target_link_libraries(${PROJECT_NAME} PRIVATE NVRam VPD MII APE) +target_link_libraries(${PROJECT_NAME} PRIVATE NVRam VPD MII APE apeloader-binary) target_link_libraries(${PROJECT_NAME} PRIVATE simulator OptParse elfio) INSTALL(TARGETS ${PROJECT_NAME} DESTINATION .) diff --git a/utils/bcmregtool/apeloader/CMakeLists.txt b/utils/bcmregtool/apeloader/CMakeLists.txt new file mode 100644 index 0000000..80c8df8 --- /dev/null +++ b/utils/bcmregtool/apeloader/CMakeLists.txt @@ -0,0 +1,66 @@ +################################################################################ +### +### @file CMakeLists.txt +### +### @project bcm5719 +### +### @brief First binary stage for the bcm5719 +### +################################################################################ +### +################################################################################ +### +### @copyright Copyright (c) 2018, Evan Lojewski +### @cond +### +### All rights reserved. +### +### Redistribution and use in source and binary forms, with or without +### modification, are permitted provided that the following conditions are met: +### 1. Redistributions of source code must retain the above copyright notice, +### this list of conditions and the following disclaimer. +### 2. 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. +### 3. Neither the name of the copyright holder 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 HOLDER 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. +### @endcond +################################################################################ + + +project(apeloader) + +# Firmware +set(LINKER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/ape.ld") +arm_add_executable(${PROJECT_NAME} + main.c + ) +arm_linker_script(${PROJECT_NAME} ${LINKER_SCRIPT}) + +target_link_libraries(${PROJECT_NAME} APE-arm) +target_link_libraries(${PROJECT_NAME} bcm5719-arm) +target_compile_options(${PROJECT_NAME} PRIVATE -nodefaultlibs) + + +# Simulator add_executable +# simulator_add_executable(sim-${PROJECT_NAME} + # init_hw.c + # main.c) + +# target_link_libraries(sim-${PROJECT_NAME} simulator) +# target_link_libraries(sim-${PROJECT_NAME} NVRam MII VPD APE) diff --git a/utils/bcmregtool/apeloader/ape.h b/utils/bcmregtool/apeloader/ape.h new file mode 100644 index 0000000..d4c9ae6 --- /dev/null +++ b/utils/bcmregtool/apeloader/ape.h @@ -0,0 +1,66 @@ +//////////////////////////////////////////////////////////////////////////////// +/// +/// @file stage1.h +/// +/// @project +/// +/// @brief Functions provided by stage1. +/// +//////////////////////////////////////////////////////////////////////////////// +/// +//////////////////////////////////////////////////////////////////////////////// +/// +/// @copyright Copyright (c) 2018, Evan Lojewski +/// @cond +/// +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without +/// modification, are permitted provided that the following conditions are met: +/// 1. Redistributions of source code must retain the above copyright notice, +/// this list of conditions and the following disclaimer. +/// 2. 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. +/// 3. Neither the name of the copyright holder 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 HOLDER 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. +/// @endcond +//////////////////////////////////////////////////////////////////////////////// + +#ifndef APE_H +#define APE_H + +// #include <bcm5719_eeprom.h> +// #include <bcm5719_GEN.h> + +// void early_init_hw(void); +// void load_nvm_config(NVRAMContents_t *nvram); +// void init_hw(NVRAMContents_t *nvram); + +#define STATUS_MAIN (0x8234700u) +#define STATUS_EARLY_INIT (0x8234800u) +#define STATUS_NVM_CONFIG (0x8234900u) +#define STATUS_INIT_HW (0x8234A00u) + +// static inline void reportStatus(uint32_t code, uint8_t step) +// { +// GEN.GenDataSig.r32 = (code | step); +// } + + +#endif /* APE_H */ diff --git a/utils/bcmregtool/apeloader/ape.ld b/utils/bcmregtool/apeloader/ape.ld new file mode 100644 index 0000000..3b26fae --- /dev/null +++ b/utils/bcmregtool/apeloader/ape.ld @@ -0,0 +1,46 @@ +OUTPUT_FORMAT(binary) +ENTRY(__start) + +SECTIONS +{ + .text 0x00100000 : ALIGN(4) SUBALIGN(4) + { + KEEP(*(.init)) + *(.text) + } + + + .data . : ALIGN(4) SUBALIGN(4) + { + *(.data*) + *(.rodata*) + } + + _fbss = .; + .bss . : ALIGN(4) SUBALIGN(4) + { + *(.bss*) + } + _ebss = .; + + + .stack . (NOLOAD) : ALIGN(4) SUBALIGN(4) + { + _fstack = .; + _estack = 00118000; + } + + + /DISCARD/ : + { + *(.comment) + *(.note.GNU-stack) + *(.eh_frame) + *(.got) + *(.ARM.exidx*) + *(.reginfo) + *(.mdebug.abi32) + *(.pdr) + } +} + diff --git a/utils/bcmregtool/apeloader/main.c b/utils/bcmregtool/apeloader/main.c new file mode 100644 index 0000000..71e25c5 --- /dev/null +++ b/utils/bcmregtool/apeloader/main.c @@ -0,0 +1,95 @@ +//////////////////////////////////////////////////////////////////////////////// +/// +/// @file main.c +/// +/// @project +/// +/// @brief Main stage1 code +/// +//////////////////////////////////////////////////////////////////////////////// +/// +//////////////////////////////////////////////////////////////////////////////// +/// +/// @copyright Copyright (c) 2018, Evan Lojewski +/// @cond +/// +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without +/// modification, are permitted provided that the following conditions are met: +/// 1. Redistributions of source code must retain the above copyright notice, +/// this list of conditions and the following disclaimer. +/// 2. 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. +/// 3. Neither the name of the copyright holder 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 HOLDER 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. +/// @endcond +//////////////////////////////////////////////////////////////////////////////// + +#include "ape.h" + +#include <APE_SHM.h> + +int __start() +{ + // Update SHM.Sig to signal ready. + SHM.SegSig.bits.Sig = SHM_SEG_SIG_SIG_LOADER; + SHM.FwStatus.bits.Ready = 1; + + for(;;) + { + uint32_t command = SHM.LoaderCommand.bits.Command; + if(!command) continue; + + uint32_t arg0 = SHM.LoaderArg0.r32; + uint32_t arg1 = SHM.LoaderArg1.r32; + + switch(command) + { + default: + break; + + case SHM_LOADER_COMMAND_COMMAND_READ_MEM: + { + // Read word address specified in arg0 + uint32_t* addr = ((void*)arg0); + SHM.LoaderArg0.r32 = *addr; + break; + } + case SHM_LOADER_COMMAND_COMMAND_WRITE_MEM: + { + // Write word address specified in arg0 with arg1 + uint32_t* addr = ((void*)arg0); + *addr = arg1; + break; + } + case SHM_LOADER_COMMAND_COMMAND_CALL: + { + // call address specified in arg0. + void (*function)(uint32_t) = ((void*)arg0); + function(arg1); + break; + } + } + + // Mark command as handled. + SHM.LoaderCommand.bits.Command = 0; + } + +}
\ No newline at end of file diff --git a/utils/bcmregtool/main.cpp b/utils/bcmregtool/main.cpp index 24fff7f..5f326e0 100644 --- a/utils/bcmregtool/main.cpp +++ b/utils/bcmregtool/main.cpp @@ -90,6 +90,45 @@ const char* regnames[32] = { "$ra", /* return address */ }; + +void boot_ape_loader() +{ + extern unsigned char apeloader_bin[]; + extern unsigned int apeloader_bin_len; + + int numWords = apeloader_bin_len/4; + + RegAPEMode_t mode = APE.Mode; + mode.bits.Halt = 1; + mode.bits.FastBoot = 1; + APE.Mode = mode; + + // We hijack the complete SHM here. + + + // load file. + for(int i = 0; i < numWords; i++) + { + SHM.write(0x0B00 + i*4, ((uint32_t*)apeloader_bin)[i]); + + printf("SHM[%d]: 0x%08X ?= 0x%08X\n", i, SHM.read(0x0B00 + i*4), ((uint32_t*)apeloader_bin)[i]); + } + + + // Mark fw as not read. + SHM.FwStatus.bits.Ready = 0; + // Start the file + APE.GpioMessage.r32 = 0x60220B00|2; + + mode.bits.Halt = 0; + mode.bits.FastBoot = 1; + mode.bits.Reset = 1; + APE.Mode = mode; + + // Wait for ready. + while(0 == SHM.FwStatus.bits.Ready); +} + const string symbol_for_address(uint32_t address, uint32_t &offset) { Elf_Half sec_num = gELFIOReader.sections.size(); @@ -317,6 +356,11 @@ int main(int argc, char const *argv[]) .action("store_true") .help("Print ape information registers."); + parser.add_option("-p", "--apeboot") + .dest("apeboot") + .metavar("APE_FILE") + .help("File to boot on the APE."); + parser.add_option("-m", "--mii") .dest("mii") .set_default("0") @@ -439,6 +483,91 @@ int main(int argc, char const *argv[]) exit(0); } + if(options.is_set("apeboot")) + { + boot_ape_loader(); + + int fileLength = 0; + int fileWords = 0; + #define NVRAM_SIZE (1024u * 256u) /* 256KB */ + + union { + uint8_t bytes[NVRAM_SIZE]; + uint32_t words[NVRAM_SIZE/4]; + } ape; + + string &file = options["apeboot"]; + + fstream infile; + infile.open(file, fstream::in | fstream::binary); + if(infile.is_open()) + { + // get length of file: + infile.seekg(0, infile.end); + fileLength = infile.tellg(); + fileWords = fileLength / 4; + infile.seekg(0, infile.beg); + + // Read in file + infile.read((char*)ape.bytes, fileLength); + + infile.close(); + } + else + { + cerr << " Unable to open file '" << file << "'" << endl; + exit(-1); + } + + if(ape.words[0] == be32toh(APE_HEADER_MAGIC)) + { + // The file is swapped... fix it. + for(int i = 0; i < sizeof(ape)/sizeof(ape.words[0]); i++) + { + ape.words[i] = be32toh(ape.words[i]); + } + } + + RegAPEMode_t mode = APE.Mode; + mode.bits.Halt = 1; + mode.bits.FastBoot = 1; + APE.Mode = mode; + + // We hijack the complete SHM here. + + + // load file. + for(int i = 0; i < fileWords; i++) + { + SHM.write(0x0B00 + i*4, ape.words[i]); + + printf("SHM[%d]: 0x%08X ?= 0x%08X\n", i, SHM.read(0x0B00 + i*4), ape.words[i]); + + // DEVICE.ApeMemoryBase.r32 = 0xD800 + (i * 4); + // DEVICE.ApeMemoryData.r32 = ape.words[i]; + } + + + + // Start the file + APE.GpioMessage.r32 = 0x60220B00|2; + + // DEVICE.ApeMemoryBase.r32 = 0xD800; + // printf("APE Memory Base: 0x%08X\n", (uint32_t)DEVICE.ApeMemoryBase.r32); + // printf("APE Memory Data: 0x%08X\n", (uint32_t)DEVICE.ApeMemoryData.r32); + // DEVICE.ApeMemoryData.r32 = ape.words[0]; + // printf("APE Memory Base: 0x%08X\n", (uint32_t)DEVICE.ApeMemoryBase.r32); + // printf("APE Memory Data: 0x%08X\n", (uint32_t)DEVICE.ApeMemoryData.r32); + // printf("ape.words[0]: 0x%08X\n", (uint32_t)ape.words[0]); + + mode.bits.Halt = 0; + mode.bits.FastBoot = 1; + mode.bits.Reset = 1; + APE.Mode = mode; + + exit(0); + } + if(options.get("ape")) { APE.Mode.print(); @@ -449,6 +578,7 @@ int main(int argc, char const *argv[]) SHM.FwVersion.print(); printf("APE SegSig: 0x%08X\n", (uint32_t)SHM.SegSig.r32); + printf("APE SegLen: 0x%08X\n", (uint32_t)SHM.ApeSegLength.r32); printf("APE RcpuApeResetCount: 0x%08X\n", (uint32_t)SHM.RcpuApeResetCount.r32); printf("APE RCPU SegSig: 0x%08X\n", (uint32_t)SHM.RcpuSegSig.r32); @@ -462,19 +592,19 @@ int main(int argc, char const *argv[]) printf("RegAPENcsiChannel0CtrlstatRx: 0x%08X\n", (uint32_t)SHM.NcsiChannel0CtrlstatRx.r32); + // boot_ape_loader(); + // printf("Loader Command: 0x%08X\n", (uint32_t)SHM.LoaderCommand.r32); + // printf("Loader Arg0: 0x%08X\n", (uint32_t)SHM.LoaderArg0.r32); + // printf("Loader Arg1: 0x%08X\n", (uint32_t)SHM.LoaderArg1.r32); - // Ensure all APE locks are released. - // APE_releaseAllLocks(); - + // SHM.LoaderArg0.r32 = 0x00100040; + // SHM.LoaderCommand.bits.Command = SHM_LOADER_COMMAND_COMMAND_READ_MEM; - APE.PerLockGrantPhy0.print(); - APE.PerLockGrantGrc.print(); - APE.PerLockGrantPhy1.print(); - APE.PerLockGrantPhy2.print(); - APE.PerLockGrantMem.print(); - APE.PerLockGrantPhy3.print(); - APE.PerLockGrantPort6.print(); - APE.PerLockGrantGpio.print(); + // // Wait for command to be handled. + // while(0 != SHM.LoaderCommand.bits.Command); + // printf("Loader Command: 0x%08X\n", (uint32_t)SHM.LoaderCommand.r32); + // printf("Loader Arg0: 0x%08X\n", (uint32_t)SHM.LoaderArg0.r32); + // printf("Loader Arg1: 0x%08X\n", (uint32_t)SHM.LoaderArg1.r32); exit(0); } |