├── .editorconfig ├── .github └── workflows │ └── main.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── include ├── CMakeLists.txt ├── local │ └── error.h ├── mailbox.h └── mailbox │ └── raspberrypi-firmware.h ├── libmailbox.pc.in ├── src ├── CMakeLists.txt ├── fd.c ├── wrap_hello.c ├── wrap_kernel.c └── wrap_ours.c └── test ├── CMakeLists.txt ├── info.c └── memflag.c /.editorconfig: -------------------------------------------------------------------------------- 1 | # .editorconfig -- Config file for EditorConfig. http://editorconfig.org/ 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | 9 | [*.{c,h}] 10 | indent_style = space 11 | indent_size = 4 12 | max_line_length = 80 13 | 14 | [include/mailbox/raspberrypi-firmware.h] 15 | indent_style = tab 16 | indent_size = 8 17 | tab_size = 8 18 | 19 | [*{CMakeLists.txt,.cmake}] 20 | indent_style = space 21 | indent_size = 4 22 | max_line_length = 80 23 | 24 | [*.yml] 25 | indent_style = space 26 | indent_size = 2 27 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | on: push 2 | 3 | jobs: 4 | 5 | build-package: 6 | runs-on: ubuntu-latest 7 | container: debian:bullseye-slim 8 | env: 9 | mailbox_version: 3.1.1 10 | strategy: 11 | matrix: 12 | include: 13 | - arch: armhf 14 | triplet: arm-linux-gnueabihf 15 | cflags: -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfloat-abi=hard -marm -mfpu=vfp 16 | - arch: arm64 17 | triplet: aarch64-linux-gnu 18 | cflags: -mcpu=cortex-a72 -mtune=cortex-a72 19 | steps: 20 | - name: Install cross toolchain 21 | env: 22 | DEBIAN_FRONTEND: noninteractive 23 | run: | 24 | dpkg --add-architecture '${{ matrix.arch }}' 25 | apt-get update 26 | apt-get install -y --no-install-recommends pkg-config cmake 'crossbuild-essential-${{ matrix.arch }}' 27 | apt-get clean 28 | rm -rf /var/lib/apt/lists/* 29 | - name: Checkout source tree 30 | uses: actions/checkout@v2 31 | - name: Build package 32 | run: | 33 | cmake -B build/ -D BUILD_TESTING=FALSE -D CPACK_DEBIAN_PACKAGE_ARCHITECTURE='${{ matrix.arch }}' -D CMAKE_C_COMPILER='${{ matrix.triplet }}-gcc' -D CMAKE_C_FLAGS='${{ matrix.cflags }}' 34 | cmake --build build/ -t package -v 35 | - name: Upload package 36 | uses: actions/upload-artifact@v2 37 | with: 38 | name: libmailbox-${{ env.mailbox_version }}-${{ matrix.arch }} 39 | path: build/libmailbox_${{ env.mailbox_version }}_${{ matrix.arch }}.deb 40 | if-no-files-found: error 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | test/info 2 | test/memflag 3 | libmailbox.pc 4 | libmailbox-*-*.deb 5 | 6 | CPackConfig.cmake 7 | CPackSourceConfig.cmake 8 | _CPack_Packages/ 9 | DartConfiguration.tcl 10 | 11 | 12 | # Created by https://www.gitignore.io/api/c,git,vim,linux,emacs,macos,cmake,windows 13 | 14 | ### C ### 15 | # Prerequisites 16 | *.d 17 | 18 | # Object files 19 | *.o 20 | *.ko 21 | *.obj 22 | *.elf 23 | 24 | # Linker output 25 | *.ilk 26 | *.map 27 | *.exp 28 | 29 | # Precompiled Headers 30 | *.gch 31 | *.pch 32 | 33 | # Libraries 34 | *.lib 35 | *.a 36 | *.la 37 | *.lo 38 | 39 | # Shared objects (inc. Windows DLLs) 40 | *.dll 41 | *.so 42 | *.so.* 43 | *.dylib 44 | 45 | # Executables 46 | *.exe 47 | *.out 48 | *.app 49 | *.i*86 50 | *.x86_64 51 | *.hex 52 | 53 | # Debug files 54 | *.dSYM/ 55 | *.su 56 | *.idb 57 | *.pdb 58 | 59 | # Kernel Module Compile Results 60 | *.mod* 61 | *.cmd 62 | .tmp_versions/ 63 | modules.order 64 | Module.symvers 65 | Mkfile.old 66 | dkms.conf 67 | 68 | ### CMake ### 69 | CMakeCache.txt 70 | CMakeFiles 71 | CMakeScripts 72 | Testing 73 | Makefile 74 | cmake_install.cmake 75 | install_manifest.txt 76 | compile_commands.json 77 | CTestTestfile.cmake 78 | build 79 | 80 | ### Emacs ### 81 | # -*- mode: gitignore; -*- 82 | *~ 83 | \#*\# 84 | /.emacs.desktop 85 | /.emacs.desktop.lock 86 | *.elc 87 | auto-save-list 88 | tramp 89 | .\#* 90 | 91 | # Org-mode 92 | .org-id-locations 93 | *_archive 94 | 95 | # flymake-mode 96 | *_flymake.* 97 | 98 | # eshell files 99 | /eshell/history 100 | /eshell/lastdir 101 | 102 | # elpa packages 103 | /elpa/ 104 | 105 | # reftex files 106 | *.rel 107 | 108 | # AUCTeX auto folder 109 | /auto/ 110 | 111 | # cask packages 112 | .cask/ 113 | dist/ 114 | 115 | # Flycheck 116 | flycheck_*.el 117 | 118 | # server auth directory 119 | /server/ 120 | 121 | # projectiles files 122 | .projectile 123 | projectile-bookmarks.eld 124 | 125 | # directory configuration 126 | .dir-locals.el 127 | 128 | # saveplace 129 | places 130 | 131 | # url cache 132 | url/cache/ 133 | 134 | # cedet 135 | ede-projects.el 136 | 137 | # smex 138 | smex-items 139 | 140 | # company-statistics 141 | company-statistics-cache.el 142 | 143 | # anaconda-mode 144 | anaconda-mode/ 145 | 146 | ### Git ### 147 | *.orig 148 | 149 | ### Linux ### 150 | 151 | # temporary files which can be created if a process still has a handle open of a deleted file 152 | .fuse_hidden* 153 | 154 | # KDE directory preferences 155 | .directory 156 | 157 | # Linux trash folder which might appear on any partition or disk 158 | .Trash-* 159 | 160 | # .nfs files are created when an open file is removed but is still being accessed 161 | .nfs* 162 | 163 | ### macOS ### 164 | *.DS_Store 165 | .AppleDouble 166 | .LSOverride 167 | 168 | # Icon must end with two \r 169 | Icon 170 | 171 | # Thumbnails 172 | ._* 173 | 174 | # Files that might appear in the root of a volume 175 | .DocumentRevisions-V100 176 | .fseventsd 177 | .Spotlight-V100 178 | .TemporaryItems 179 | .Trashes 180 | .VolumeIcon.icns 181 | .com.apple.timemachine.donotpresent 182 | 183 | # Directories potentially created on remote AFP share 184 | .AppleDB 185 | .AppleDesktop 186 | Network Trash Folder 187 | Temporary Items 188 | .apdisk 189 | 190 | ### Vim ### 191 | # swap 192 | .sw[a-p] 193 | .*.sw[a-p] 194 | # session 195 | Session.vim 196 | # temporary 197 | .netrwhist 198 | # auto-generated tag files 199 | tags 200 | 201 | ### Windows ### 202 | # Windows thumbnail cache files 203 | Thumbs.db 204 | ehthumbs.db 205 | ehthumbs_vista.db 206 | 207 | # Folder config file 208 | Desktop.ini 209 | 210 | # Recycle Bin used on file shares 211 | $RECYCLE.BIN/ 212 | 213 | # Windows Installer files 214 | *.cab 215 | *.msi 216 | *.msm 217 | *.msp 218 | 219 | # Windows shortcuts 220 | *.lnk 221 | 222 | 223 | # End of https://www.gitignore.io/api/c,git,vim,linux,emacs,macos,cmake,windows 224 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # For CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT 2 | cmake_minimum_required(VERSION 3.7.2) 3 | 4 | project(libmailbox VERSION 3.1.1 LANGUAGES C 5 | DESCRIPTION "A wrapper library for Mailbox interface of Raspberry Pi") 6 | 7 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_DESCRIPTION}) 8 | set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) 9 | set(CPACK_PACKAGE_CONTACT "Yukimasa Sugizaki ") 10 | set(CPACK_GENERATOR DEB) 11 | set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) 12 | set(CPACK_DEBIAN_PACKAGE_DEPENDS libc6) 13 | 14 | # CMAKE_INSTALL_PREFIX and CPACK_PACKAGING_INSTALL_PREFIX must be identical 15 | # because the install prefix is used in the pkg-config file which will be 16 | # auto-generated. 17 | if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 18 | set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "Install prefix" FORCE) 19 | endif() 20 | set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") 21 | message(STATUS "Install prefix is set to ${CMAKE_INSTALL_PREFIX}") 22 | 23 | include(CPack) 24 | 25 | include(GNUInstallDirs) 26 | 27 | add_subdirectory(src) 28 | add_subdirectory(include) 29 | add_subdirectory(test) 30 | 31 | configure_file(libmailbox.pc.in libmailbox.pc @ONLY) 32 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libmailbox.pc" 33 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2015 Sugizaki Yukimasa 2 | Copyright (c) 2018 Idein Inc. ( http://idein.jp/ ) 3 | All rights reserved. 4 | 5 | 6 | Modified (3-Clause) BSD License 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions 10 | are met: 11 | 1. Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | 2. Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in the 15 | documentation and/or other materials provided with the distribution. 16 | 3. The name of the author may not be used to endorse or promote products 17 | derived from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mailbox 2 | 3 | A library for accessing the Mailbox interface (`/dev/vcio`) on Raspberry Pi. 4 | 5 | 6 | ## Installation 7 | 8 | ``` 9 | $ git clone https://github.com/Terminus-IMRC/mailbox 10 | $ cd mailbox/ 11 | $ cmake -B build/ 12 | $ cmake --build build/ -t package 13 | $ sudo dpkg -i libmailbox-x.y.z-arch.deb 14 | ``` 15 | 16 | 17 | ## Running tests 18 | 19 | ``` 20 | $ cd build/ 21 | $ ctest -V 22 | ``` 23 | -------------------------------------------------------------------------------- /include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | install(FILES mailbox.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") 2 | install(FILES mailbox/raspberrypi-firmware.h 3 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/mailbox") 4 | -------------------------------------------------------------------------------- /include/local/error.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Idein Inc. ( http://idein.jp/ ) 3 | * All rights reserved. 4 | * 5 | * This software is licensed under a Modified (3-Clause) BSD License. 6 | * You should have received a copy of this license along with this 7 | * software. If not, contact the copyright holder above. 8 | */ 9 | 10 | #ifndef LOCAL_ERROR_H_ 11 | #define LOCAL_ERROR_H_ 12 | 13 | #include 14 | 15 | #define print_error(fmt, ...) \ 16 | do { \ 17 | fprintf(stderr, "%s:%u:%s: error: " fmt, \ 18 | __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ 19 | } while (0) 20 | 21 | #endif /* LOCAL_ERROR_H_ */ 22 | -------------------------------------------------------------------------------- /include/mailbox.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Idein Inc. ( http://idein.jp/ ) 3 | * All rights reserved. 4 | * 5 | * This software is licensed under a Modified (3-Clause) BSD License. 6 | * You should have received a copy of this license along with this 7 | * software. If not, contact the copyright holder above. 8 | */ 9 | 10 | #ifndef MAILBOX_H_ 11 | #define MAILBOX_H_ 12 | 13 | #include 14 | #include 15 | 16 | int mailbox_open(void); 17 | int mailbox_close(const int fd); 18 | 19 | /* Raw ioctl. */ 20 | int mailbox_property(const int fd, void *buf); 21 | 22 | /* Official-kernel-driver-like wrappers. */ 23 | int rpi_firmware_property_list(const int fd, void *data, uint32_t tag_size); 24 | int rpi_firmware_property(const int fd, const uint32_t tag, void *tag_data, 25 | const uint32_t buf_size, const uint32_t req_resp_size); 26 | 27 | /* hello_pi/hello_fft-like userland wrappers. */ 28 | uint32_t mailbox_mem_alloc(const int fd, const uint32_t size, 29 | const uint32_t align, const uint32_t flags); 30 | int mailbox_mem_free(const int fd, const uint32_t handle); 31 | uint32_t mailbox_mem_lock(const int fd, const uint32_t handle); 32 | int mailbox_mem_unlock(const int fd, const uint32_t busaddr); 33 | int mailbox_execute_code(const int fd, const uint32_t code, 34 | const uint32_t r0, const uint32_t r1, const uint32_t r2, 35 | const uint32_t r3, const uint32_t r4, const uint32_t r5); 36 | int mailbox_qpu_execute(const int fd, const uint32_t num_qpus, 37 | const uint32_t control, const uint32_t noflush, 38 | const uint32_t timeout); 39 | int mailbox_qpu_enable(const int fd, const uint32_t enable); 40 | 41 | /* Our original wrappers. */ 42 | int mailbox_get_firmware_revision(const int fd, 43 | uint32_t *firmware_revision); 44 | int mailbox_get_board_model(const int fd, uint32_t *board_model); 45 | int mailbox_get_board_revision(const int fd, uint32_t *board_revision); 46 | int mailbox_get_board_mac_address(const int fd, uint64_t *mac_address); 47 | int mailbox_get_board_serial(const int fd, uint64_t *board_serial); 48 | int mailbox_get_arm_memory(const int fd, uint32_t *base, uint32_t *size); 49 | int mailbox_get_vc_memory(const int fd, uint32_t *base, uint32_t *size); 50 | 51 | /* 52 | * Derived from 53 | * https://github.com/raspberrypi/linux/blob/rpi-4.14.y/drivers/char/broadcom/vcio.c 54 | */ 55 | #define VCIO_IOC_MAGIC 100 56 | #define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *) 57 | 58 | #define VCIO_FILE_NAME "/dev/vcio" 59 | 60 | #define MEM_FLAG_DISCARDABLE (1<<0) 61 | #define MEM_FLAG_NORMAL (0<<2) 62 | #define MEM_FLAG_DIRECT (1<<2) 63 | #define MEM_FLAG_COHERENT (1<<3) 64 | #define MEM_FLAG_L1_NONALLOCATING (MEM_FLAG_DIRECT | MEM_FLAG_COHERENT) 65 | #define MEM_FLAG_ZERO (1<<4) 66 | #define MEM_FLAG_NO_INIT (1<<5) 67 | #define MEM_FLAG_HINT_PERMALOCK (1<<6) 68 | 69 | #endif /* MAILBOX_H_ */ 70 | -------------------------------------------------------------------------------- /include/mailbox/raspberrypi-firmware.h: -------------------------------------------------------------------------------- 1 | /* 2 | * raspberrypi-firmware.h 3 | * 4 | * This file was derived from 5 | * https://github.com/raspberrypi/linux/blob/rpi-4.14.y/include/soc/bcm2835/raspberrypi-firmware.h 6 | * and removed some lines to pass build on userland. 7 | */ 8 | 9 | /* 10 | * Copyright © 2015 Broadcom 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License version 2 as 14 | * published by the Free Software Foundation. 15 | */ 16 | 17 | #ifndef __SOC_RASPBERRY_FIRMWARE_H__ 18 | #define __SOC_RASPBERRY_FIRMWARE_H__ 19 | 20 | #include 21 | 22 | enum rpi_firmware_property_status { 23 | RPI_FIRMWARE_STATUS_REQUEST = 0, 24 | RPI_FIRMWARE_STATUS_SUCCESS = 0x80000000, 25 | RPI_FIRMWARE_STATUS_ERROR = 0x80000001, 26 | }; 27 | 28 | /** 29 | * struct rpi_firmware_property_tag_header - Firmware property tag header 30 | * @tag: One of enum_mbox_property_tag. 31 | * @buf_size: The number of bytes in the value buffer following this 32 | * struct. 33 | * @req_resp_size: On submit, the length of the request (though it doesn't 34 | * appear to be currently used by the firmware). On return, 35 | * the length of the response (always 4 byte aligned), with 36 | * the low bit set. 37 | */ 38 | struct rpi_firmware_property_tag_header { 39 | uint32_t tag; 40 | uint32_t buf_size; 41 | uint32_t req_resp_size; 42 | }; 43 | 44 | enum rpi_firmware_property_tag { 45 | RPI_FIRMWARE_PROPERTY_END = 0, 46 | RPI_FIRMWARE_GET_FIRMWARE_REVISION = 0x00000001, 47 | 48 | RPI_FIRMWARE_SET_CURSOR_INFO = 0x00008010, 49 | RPI_FIRMWARE_SET_CURSOR_STATE = 0x00008011, 50 | 51 | RPI_FIRMWARE_GET_BOARD_MODEL = 0x00010001, 52 | RPI_FIRMWARE_GET_BOARD_REVISION = 0x00010002, 53 | RPI_FIRMWARE_GET_BOARD_MAC_ADDRESS = 0x00010003, 54 | RPI_FIRMWARE_GET_BOARD_SERIAL = 0x00010004, 55 | RPI_FIRMWARE_GET_ARM_MEMORY = 0x00010005, 56 | RPI_FIRMWARE_GET_VC_MEMORY = 0x00010006, 57 | RPI_FIRMWARE_GET_CLOCKS = 0x00010007, 58 | RPI_FIRMWARE_GET_POWER_STATE = 0x00020001, 59 | RPI_FIRMWARE_GET_TIMING = 0x00020002, 60 | RPI_FIRMWARE_SET_POWER_STATE = 0x00028001, 61 | RPI_FIRMWARE_GET_CLOCK_STATE = 0x00030001, 62 | RPI_FIRMWARE_GET_CLOCK_RATE = 0x00030002, 63 | RPI_FIRMWARE_GET_VOLTAGE = 0x00030003, 64 | RPI_FIRMWARE_GET_MAX_CLOCK_RATE = 0x00030004, 65 | RPI_FIRMWARE_GET_MAX_VOLTAGE = 0x00030005, 66 | RPI_FIRMWARE_GET_TEMPERATURE = 0x00030006, 67 | RPI_FIRMWARE_GET_MIN_CLOCK_RATE = 0x00030007, 68 | RPI_FIRMWARE_GET_MIN_VOLTAGE = 0x00030008, 69 | RPI_FIRMWARE_GET_TURBO = 0x00030009, 70 | RPI_FIRMWARE_GET_MAX_TEMPERATURE = 0x0003000a, 71 | RPI_FIRMWARE_GET_STC = 0x0003000b, 72 | RPI_FIRMWARE_ALLOCATE_MEMORY = 0x0003000c, 73 | RPI_FIRMWARE_LOCK_MEMORY = 0x0003000d, 74 | RPI_FIRMWARE_UNLOCK_MEMORY = 0x0003000e, 75 | RPI_FIRMWARE_RELEASE_MEMORY = 0x0003000f, 76 | RPI_FIRMWARE_EXECUTE_CODE = 0x00030010, 77 | RPI_FIRMWARE_EXECUTE_QPU = 0x00030011, 78 | RPI_FIRMWARE_SET_ENABLE_QPU = 0x00030012, 79 | RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, 80 | RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, 81 | RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021, 82 | RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030, 83 | RPI_FIRMWARE_GET_THROTTLED = 0x00030046, 84 | RPI_FIRMWARE_SET_CLOCK_STATE = 0x00038001, 85 | RPI_FIRMWARE_SET_CLOCK_RATE = 0x00038002, 86 | RPI_FIRMWARE_SET_VOLTAGE = 0x00038003, 87 | RPI_FIRMWARE_SET_TURBO = 0x00038009, 88 | RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021, 89 | RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030, 90 | RPI_FIRMWARE_GET_GPIO_STATE = 0x00030041, 91 | RPI_FIRMWARE_SET_GPIO_STATE = 0x00038041, 92 | RPI_FIRMWARE_SET_SDHOST_CLOCK = 0x00038042, 93 | RPI_FIRMWARE_GET_GPIO_CONFIG = 0x00030043, 94 | RPI_FIRMWARE_SET_GPIO_CONFIG = 0x00038043, 95 | RPI_FIRMWARE_GET_PERIPH_REG = 0x00030045, 96 | RPI_FIRMWARE_SET_PERIPH_REG = 0x00038045, 97 | 98 | 99 | /* Dispmanx TAGS */ 100 | RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, 101 | RPI_FIRMWARE_FRAMEBUFFER_BLANK = 0x00040002, 102 | RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, 103 | RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, 104 | RPI_FIRMWARE_FRAMEBUFFER_GET_DEPTH = 0x00040005, 105 | RPI_FIRMWARE_FRAMEBUFFER_GET_PIXEL_ORDER = 0x00040006, 106 | RPI_FIRMWARE_FRAMEBUFFER_GET_ALPHA_MODE = 0x00040007, 107 | RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH = 0x00040008, 108 | RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET = 0x00040009, 109 | RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN = 0x0004000a, 110 | RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE = 0x0004000b, 111 | RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, 112 | RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010, 113 | RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, 114 | RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, 115 | RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, 116 | RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH = 0x00044005, 117 | RPI_FIRMWARE_FRAMEBUFFER_TEST_PIXEL_ORDER = 0x00044006, 118 | RPI_FIRMWARE_FRAMEBUFFER_TEST_ALPHA_MODE = 0x00044007, 119 | RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET = 0x00044009, 120 | RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN = 0x0004400a, 121 | RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE = 0x0004400b, 122 | RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC = 0x0004400e, 123 | RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, 124 | RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, 125 | RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH = 0x00048005, 126 | RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER = 0x00048006, 127 | RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE = 0x00048007, 128 | RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET = 0x00048009, 129 | RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN = 0x0004800a, 130 | RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE = 0x0004800b, 131 | RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF = 0x0004801f, 132 | RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF = 0x00048020, 133 | RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC = 0x0004800e, 134 | RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT = 0x0004800f, 135 | 136 | RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, 137 | 138 | RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, 139 | RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, 140 | }; 141 | 142 | #endif /* __SOC_RASPBERRY_FIRMWARE_H__ */ 143 | -------------------------------------------------------------------------------- /libmailbox.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CPACK_PACKAGING_INSTALL_PREFIX@ 2 | libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ 3 | includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ 4 | 5 | Name: @CPACK_PACKAGE_NAME@ 6 | Description: @CPACK_PACKAGE_DESCRIPTION_SUMMARY@ 7 | Version: @CPACK_PACKAGE_VERSION@ 8 | Libs: -L${libdir} -lmailbox 9 | Cflags: -I${includedir} 10 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories("${CMAKE_SOURCE_DIR}/include") 2 | add_compile_options(-W -Wall -Wextra -pipe -O2) 3 | 4 | set(mailbox_SOURCES fd.c wrap_kernel.c wrap_hello.c wrap_ours.c) 5 | add_library(mailbox SHARED ${mailbox_SOURCES}) 6 | add_library(mailbox-static STATIC ${mailbox_SOURCES}) 7 | set_target_properties(mailbox-static PROPERTIES OUTPUT_NAME mailbox) 8 | 9 | install(TARGETS mailbox LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") 10 | install(TARGETS mailbox-static ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}") 11 | -------------------------------------------------------------------------------- /src/fd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Idein Inc. ( http://idein.jp/ ) 3 | * All rights reserved. 4 | * 5 | * This software is licensed under a Modified (3-Clause) BSD License. 6 | * You should have received a copy of this license along with this 7 | * software. If not, contact the copyright holder above. 8 | */ 9 | 10 | #include "mailbox.h" 11 | #include "local/error.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | int mailbox_open(void) 21 | { 22 | int fd; 23 | 24 | fd = open(VCIO_FILE_NAME, O_NONBLOCK); 25 | if (fd == -1) { 26 | print_error("open: %s: %s\n", VCIO_FILE_NAME, strerror(errno)); 27 | return -1; 28 | } 29 | 30 | return fd; 31 | } 32 | 33 | int mailbox_close(const int fd) 34 | { 35 | int err; 36 | 37 | err = close(fd); 38 | if (err) { 39 | print_error("close: %s\n", strerror(errno)); 40 | return err; 41 | } 42 | 43 | return 0; 44 | } 45 | 46 | int mailbox_property(const int fd, void *buf) 47 | { 48 | int err; 49 | 50 | err = ioctl(fd, IOCTL_MBOX_PROPERTY, buf); 51 | if (err) { 52 | print_error("ioctl: IOCTL_MBOX_PROPERTY: %s\n", strerror(errno)); 53 | return err; 54 | } 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /src/wrap_hello.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Idein Inc. ( http://idein.jp/ ) 3 | * All rights reserved. 4 | * 5 | * This software is licensed under a Modified (3-Clause) BSD License. 6 | * You should have received a copy of this license along with this 7 | * software. If not, contact the copyright holder above. 8 | */ 9 | 10 | #include "mailbox.h" 11 | #include "local/error.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | uint32_t mailbox_mem_alloc(const int fd, const uint32_t size, 18 | const uint32_t align, const uint32_t flags) 19 | { 20 | union { 21 | struct { 22 | uint32_t size, align, flags; 23 | } in; 24 | struct { 25 | uint32_t handle; 26 | } out; 27 | } msg = { 28 | .in = { 29 | .size = size, 30 | .align = align, 31 | .flags = flags 32 | } 33 | }; 34 | int err; 35 | 36 | err = rpi_firmware_property(fd, RPI_FIRMWARE_ALLOCATE_MEMORY, &msg, 37 | sizeof(msg.in), sizeof(msg.out)); 38 | if (err) 39 | return 0; 40 | 41 | return msg.out.handle; 42 | } 43 | 44 | int mailbox_mem_free(const int fd, const uint32_t handle) 45 | { 46 | union { 47 | struct { 48 | uint32_t handle; 49 | } in; 50 | struct { 51 | uint32_t status; 52 | } out; 53 | } msg = { 54 | .in = { 55 | .handle = handle 56 | } 57 | }; 58 | int err; 59 | 60 | err = rpi_firmware_property(fd, RPI_FIRMWARE_RELEASE_MEMORY, &msg, 61 | sizeof(msg.in), sizeof(msg.out)); 62 | if (err) 63 | return err; 64 | else if (msg.out.status) { 65 | print_error("status=0x%08" PRIx32 "\n", msg.out.status); 66 | return msg.out.status; 67 | } 68 | 69 | return 0; 70 | } 71 | 72 | uint32_t mailbox_mem_lock(const int fd, const uint32_t handle) 73 | { 74 | union { 75 | struct { 76 | uint32_t handle; 77 | } in; 78 | struct { 79 | uint32_t busaddr; 80 | } out; 81 | } msg = { 82 | .in = { 83 | .handle = handle 84 | } 85 | }; 86 | int err; 87 | 88 | err = rpi_firmware_property(fd, RPI_FIRMWARE_LOCK_MEMORY, &msg, 89 | sizeof(msg.in), sizeof(msg.out)); 90 | if (err) 91 | return 0; 92 | 93 | return msg.out.busaddr; 94 | } 95 | 96 | int mailbox_mem_unlock(const int fd, const uint32_t busaddr) 97 | { 98 | union { 99 | struct { 100 | uint32_t busaddr; 101 | } in; 102 | struct { 103 | uint32_t status; 104 | } out; 105 | } msg = { 106 | .in = { 107 | .busaddr = busaddr 108 | } 109 | }; 110 | int err; 111 | 112 | err = rpi_firmware_property(fd, RPI_FIRMWARE_UNLOCK_MEMORY, &msg, 113 | sizeof(msg.in), sizeof(msg.out)); 114 | if (err) 115 | return err; 116 | else if (msg.out.status) { 117 | print_error("status=0x%08" PRIx32 "\n", msg.out.status); 118 | return msg.out.status; 119 | } 120 | 121 | return 0; 122 | } 123 | 124 | int mailbox_execute_code(const int fd, const uint32_t code, const uint32_t r0, 125 | const uint32_t r1, const uint32_t r2, const uint32_t r3, 126 | const uint32_t r4, const uint32_t r5) 127 | { 128 | union { 129 | struct { 130 | uint32_t code, r0, r1, r2, r3, r4, r5; 131 | } in; 132 | struct { 133 | uint32_t r0; 134 | } out; 135 | } msg = { 136 | .in = { 137 | .code = code, 138 | .r0 = r0, 139 | .r1 = r1, 140 | .r2 = r2, 141 | .r3 = r3, 142 | .r4 = r4, 143 | .r5 = r5 144 | } 145 | }; 146 | int err; 147 | 148 | err = rpi_firmware_property(fd, RPI_FIRMWARE_EXECUTE_CODE, &msg, 149 | sizeof(msg.in), sizeof(msg.out)); 150 | if (err) 151 | return err; 152 | 153 | return msg.out.r0; 154 | } 155 | 156 | int mailbox_qpu_execute(const int fd, const uint32_t num_qpus, 157 | const uint32_t control, const uint32_t noflush, 158 | const uint32_t timeout) 159 | { 160 | union { 161 | struct { 162 | uint32_t num_qpus, control, noflush, timeout; 163 | } in; 164 | struct { 165 | uint32_t status; 166 | } out; 167 | } msg = { 168 | .in = { 169 | .num_qpus = num_qpus, 170 | .control = control, 171 | .noflush = noflush, 172 | .timeout = timeout 173 | } 174 | }; 175 | int err; 176 | 177 | err = rpi_firmware_property(fd, RPI_FIRMWARE_EXECUTE_QPU, &msg, 178 | sizeof(msg.in), sizeof(msg.out)); 179 | if (err) 180 | return err; 181 | else if (msg.out.status) { 182 | if (msg.out.status == 0x80000000) 183 | print_error("Execution timeout (timeout=%" PRIu32 "ms)\n", 184 | timeout); 185 | else 186 | print_error("Unknown status: 0x%08" PRIx32 "\n", 187 | msg.out.status); 188 | return msg.out.status; 189 | } 190 | 191 | return 0; 192 | } 193 | 194 | int mailbox_qpu_enable(const int fd, const uint32_t enable) 195 | { 196 | union { 197 | struct { 198 | uint32_t enable; 199 | } in; 200 | struct { 201 | uint32_t status; 202 | } out; 203 | } msg = { 204 | .in = { 205 | .enable = enable 206 | } 207 | }; 208 | int err; 209 | 210 | err = rpi_firmware_property(fd, RPI_FIRMWARE_SET_ENABLE_QPU, &msg, 211 | sizeof(msg.in), sizeof(msg.out)); 212 | if (err) 213 | return err; 214 | else if (msg.out.status) { 215 | print_error("status=0x%08" PRIx32 "\n", msg.out.status); 216 | return msg.out.status; 217 | } 218 | 219 | return 0; 220 | } 221 | -------------------------------------------------------------------------------- /src/wrap_kernel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Idein Inc. ( http://idein.jp/ ) 3 | * All rights reserved. 4 | * 5 | * This software is licensed under a Modified (3-Clause) BSD License. 6 | * You should have received a copy of this license along with this 7 | * software. If not, contact the copyright holder above. 8 | */ 9 | 10 | #include "mailbox.h" 11 | #include "local/error.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include /* for MAX() */ 17 | 18 | int rpi_firmware_property_list(const int fd, void *data, uint32_t tag_size) 19 | { 20 | int err; 21 | uint32_t *buf; 22 | const uint32_t size = sizeof(*buf)*2 + tag_size + sizeof(*buf)*1; 23 | 24 | buf = malloc(size); 25 | if (buf == NULL) { 26 | print_error("malloc: %s\n", strerror(errno)); 27 | return 1; 28 | } 29 | 30 | buf[0] = size; 31 | buf[1] = RPI_FIRMWARE_STATUS_REQUEST; 32 | memcpy(buf + 2, data, tag_size); 33 | buf[size/4 - 1] = RPI_FIRMWARE_PROPERTY_END; 34 | 35 | err = mailbox_property(fd, buf); 36 | if (err) { 37 | goto out; 38 | } 39 | if (buf[1] != RPI_FIRMWARE_STATUS_SUCCESS) { 40 | print_error("Request failed: 0x%08" PRIx32 "\n", buf[1]); 41 | err = 1; 42 | goto out; 43 | } 44 | 45 | memcpy(data, buf + 2, tag_size); 46 | 47 | out: 48 | free(buf); 49 | return err; 50 | } 51 | 52 | int rpi_firmware_property(const int fd, const uint32_t tag, void *tag_data, 53 | const uint32_t buf_size, const uint32_t req_resp_size) 54 | { 55 | int err; 56 | const unsigned data_size = 57 | sizeof(struct rpi_firmware_property_tag_header) + buf_size; 58 | void *data = alloca(data_size); 59 | struct rpi_firmware_property_tag_header *header = 60 | (struct rpi_firmware_property_tag_header*) data; 61 | 62 | if (buf_size < req_resp_size) { 63 | print_error("buf_size < req_resp_size\n"); 64 | return 1; 65 | } 66 | 67 | header->tag = tag; 68 | header->buf_size = buf_size; 69 | header->req_resp_size = req_resp_size; 70 | memcpy(data + sizeof(*header), tag_data, buf_size); 71 | 72 | err = rpi_firmware_property_list(fd, data, data_size); 73 | if (err) 74 | return err; 75 | if (!(header->req_resp_size & (1UL<<31))) { 76 | print_error("header->req_resp_size[31] was not set by firmware\n"); 77 | return 1; 78 | } 79 | header->req_resp_size &= ~(1UL<<31); 80 | if (header->req_resp_size != req_resp_size) { 81 | print_error("Firmware requires %" PRIu32 " bytes for response buffer " 82 | "while you think it is %" PRIu32 " bytes\n", 83 | header->req_resp_size, req_resp_size); 84 | print_error("Note: req_resp_size seems not to be used in the firmware " 85 | "for now, but we require users to set this to proper value\n"); 86 | return 1; 87 | } 88 | if (header->req_resp_size > buf_size) { 89 | print_error("Firmware requires %" PRIu32 " bytes for response buffer " 90 | "while the supplied buffer is only %" PRIu32 " bytes\n", 91 | header->req_resp_size, buf_size); 92 | return 1; 93 | } 94 | 95 | memcpy(tag_data, data + sizeof(*header), req_resp_size); 96 | 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /src/wrap_ours.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Idein Inc. ( http://idein.jp/ ) 3 | * All rights reserved. 4 | * 5 | * This software is licensed under a Modified (3-Clause) BSD License. 6 | * You should have received a copy of this license along with this 7 | * software. If not, contact the copyright holder above. 8 | */ 9 | 10 | #include "mailbox.h" 11 | #include 12 | 13 | int mailbox_get_firmware_revision(const int fd, 14 | uint32_t *firmware_revision) 15 | { 16 | union { 17 | struct { 18 | } in; 19 | struct { 20 | uint32_t firmware_revision; 21 | } out; 22 | } msg = { 23 | .in = { 24 | } 25 | }; 26 | int err; 27 | 28 | err = rpi_firmware_property(fd, RPI_FIRMWARE_GET_FIRMWARE_REVISION, &msg, 29 | sizeof(msg), sizeof(msg.out)); 30 | if (err) 31 | return err; 32 | 33 | *firmware_revision = msg.out.firmware_revision; 34 | return 0; 35 | } 36 | 37 | int mailbox_get_board_model(const int fd, uint32_t *board_model) 38 | { 39 | union { 40 | struct { 41 | uint32_t aa; 42 | } in; 43 | struct { 44 | uint32_t board_model; 45 | } out; 46 | } msg = { 47 | .in = { 48 | } 49 | }; 50 | int err; 51 | 52 | err = rpi_firmware_property(fd, RPI_FIRMWARE_GET_BOARD_MODEL, &msg, 53 | sizeof(msg), sizeof(msg.out)); 54 | if (err) 55 | return err; 56 | 57 | *board_model = msg.out.board_model; 58 | return 0; 59 | } 60 | 61 | int mailbox_get_board_revision(const int fd, uint32_t *board_revision) 62 | { 63 | union { 64 | struct { 65 | } in; 66 | struct { 67 | uint32_t board_revision; 68 | } out; 69 | } msg = { 70 | .in = { 71 | } 72 | }; 73 | int err; 74 | 75 | err = rpi_firmware_property(fd, RPI_FIRMWARE_GET_BOARD_REVISION, &msg, 76 | sizeof(msg), sizeof(msg.out)); 77 | if (err) 78 | return err; 79 | 80 | *board_revision = msg.out.board_revision; 81 | return 0; 82 | } 83 | 84 | int mailbox_get_board_mac_address(const int fd, uint64_t *mac_address) 85 | { 86 | union { 87 | struct { 88 | uint64_t dummy; 89 | } in; 90 | struct { 91 | uint8_t v0, v1, v2, v3, v4, v5; 92 | } out; 93 | } msg = { 94 | .in = { 95 | } 96 | }; 97 | int err; 98 | 99 | err = rpi_firmware_property(fd, RPI_FIRMWARE_GET_BOARD_MAC_ADDRESS, &msg, 100 | sizeof(msg), sizeof(msg.out)); 101 | if (err) 102 | return err; 103 | 104 | *mac_address = 105 | ((uint64_t) msg.out.v5) << 0 106 | | ((uint64_t) msg.out.v4) << 8 107 | | ((uint64_t) msg.out.v3) << 16 108 | | ((uint64_t) msg.out.v2) << 24 109 | | ((uint64_t) msg.out.v1) << 32 110 | | ((uint64_t) msg.out.v0) << 40; 111 | return 0; 112 | } 113 | 114 | int mailbox_get_board_serial(const int fd, uint64_t *board_serial) 115 | { 116 | union { 117 | struct { 118 | } in; 119 | struct { 120 | uint64_t board_serial; 121 | } out; 122 | } msg = { 123 | .in = { 124 | } 125 | }; 126 | int err; 127 | 128 | err = rpi_firmware_property(fd, RPI_FIRMWARE_GET_BOARD_SERIAL, &msg, 129 | sizeof(msg), sizeof(msg.out)); 130 | if (err) 131 | return err; 132 | 133 | *board_serial = msg.out.board_serial; 134 | return 0; 135 | } 136 | 137 | int mailbox_get_arm_memory(const int fd, uint32_t *base, uint32_t *size) 138 | { 139 | union { 140 | struct { 141 | } in; 142 | struct { 143 | uint32_t base, size; 144 | } out; 145 | } msg = { 146 | .in = { 147 | } 148 | }; 149 | int err; 150 | 151 | err = rpi_firmware_property(fd, RPI_FIRMWARE_GET_ARM_MEMORY, &msg, 152 | sizeof(msg), sizeof(msg.out)); 153 | if (err) 154 | return err; 155 | 156 | *base = msg.out.base; 157 | *size = msg.out.size; 158 | return 0; 159 | } 160 | 161 | int mailbox_get_vc_memory(const int fd, uint32_t *base, uint32_t *size) 162 | { 163 | union { 164 | struct { 165 | } in; 166 | struct { 167 | uint32_t base, size; 168 | } out; 169 | } msg = { 170 | .in = { 171 | } 172 | }; 173 | int err; 174 | 175 | err = rpi_firmware_property(fd, RPI_FIRMWARE_GET_VC_MEMORY, &msg, 176 | sizeof(msg), sizeof(msg.out)); 177 | if (err) 178 | return err; 179 | 180 | *base = msg.out.base; 181 | *size = msg.out.size; 182 | return 0; 183 | } 184 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(CTest) 2 | 3 | if (NOT BUILD_TESTING) 4 | return() 5 | endif () 6 | 7 | include_directories("${CMAKE_SOURCE_DIR}/include") 8 | add_compile_options(-W -Wall -Wextra -pipe -O2) 9 | 10 | add_executable(info info.c) 11 | target_link_libraries(info LINK_PUBLIC mailbox) 12 | add_test(Info info) 13 | 14 | add_executable(memflag memflag.c) 15 | target_link_libraries(memflag LINK_PUBLIC mailbox) 16 | add_test(MemFlag memflag) 17 | -------------------------------------------------------------------------------- /test/info.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Idein Inc. ( http://idein.jp/ ) 3 | * All rights reserved. 4 | * 5 | * This software is licensed under a Modified (3-Clause) BSD License. 6 | * You should have received a copy of this license along with this 7 | * software. If not, contact the copyright holder above. 8 | */ 9 | 10 | #include "mailbox.h" 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | int main(void) 17 | { 18 | int mbfd; 19 | int err; 20 | 21 | mbfd = mailbox_open(); 22 | if (mbfd == -1) 23 | return 1; 24 | 25 | { 26 | uint32_t rev; 27 | time_t t; 28 | char s[256]; 29 | err = mailbox_get_firmware_revision(mbfd, &rev); 30 | if (err) 31 | return err; 32 | t = (time_t) rev; 33 | strftime(s, sizeof(s), "%b %e %Y %T", gmtime(&t)); 34 | printf("Firmware revision: %s\n", s); 35 | } 36 | { 37 | uint32_t model; 38 | err = mailbox_get_board_model(mbfd, &model); 39 | if (err) 40 | return err; 41 | printf("Board model: 0x%08" PRIx32 "\n", model); 42 | } 43 | { 44 | uint32_t rev; 45 | err = mailbox_get_board_revision(mbfd, &rev); 46 | if (err) 47 | return err; 48 | printf("Board revision: 0x%08" PRIx32 "\n", rev); 49 | } 50 | { 51 | uint64_t mac; 52 | err = mailbox_get_board_mac_address(mbfd, &mac); 53 | if (err) 54 | return err; 55 | printf("Board MAC address: %012" PRIx64 "\n", mac); 56 | } 57 | { 58 | uint64_t serial; 59 | err = mailbox_get_board_serial(mbfd, &serial); 60 | if (err) 61 | return err; 62 | printf("Board serial: 0x%" PRIx64 "\n", serial); 63 | } 64 | { 65 | uint32_t base, size; 66 | err = mailbox_get_arm_memory(mbfd, &base, &size); 67 | if (err) 68 | return err; 69 | printf("ARM memory: 0x%08" PRIx32 " bytes at 0x%08" PRIx32 "\n", 70 | size, base); 71 | } 72 | { 73 | uint32_t base, size; 74 | err = mailbox_get_vc_memory(mbfd, &base, &size); 75 | if (err) 76 | return err; 77 | printf("VC memory: 0x%08" PRIx32 " bytes at 0x%08" PRIx32 "\n", 78 | size, base); 79 | } 80 | 81 | err = mailbox_close(mbfd); 82 | return err; 83 | } 84 | -------------------------------------------------------------------------------- /test/memflag.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Idein Inc. ( http://idein.jp/ ) 3 | * All rights reserved. 4 | * 5 | * This software is licensed under a Modified (3-Clause) BSD License. 6 | * You should have received a copy of this license along with this 7 | * software. If not, contact the copyright holder above. 8 | */ 9 | 10 | #include "mailbox.h" 11 | #include 12 | #include 13 | #include 14 | 15 | static int print_addr(const int mbfd, const uint32_t flags) 16 | { 17 | uint32_t handle, busaddr; 18 | int err; 19 | 20 | handle = mailbox_mem_alloc(mbfd, 4096, 4096, flags); 21 | if (!handle) 22 | goto err_out; 23 | 24 | busaddr = mailbox_mem_lock(mbfd, handle); 25 | if (!busaddr) 26 | goto err_free; 27 | 28 | printf("0x%08" PRIx32 "\n", busaddr); 29 | 30 | err = mailbox_mem_unlock(mbfd, busaddr); 31 | if (err) 32 | goto err_free; 33 | 34 | err = mailbox_mem_free(mbfd, handle); 35 | if (err) 36 | goto err_out; 37 | 38 | return 0; 39 | 40 | err_free: 41 | (void) mailbox_mem_free(mbfd, handle); 42 | err_out: 43 | return 1; 44 | } 45 | 46 | int main(void) 47 | { 48 | int mbfd; 49 | int err; 50 | 51 | mbfd = mailbox_open(); 52 | if (mbfd == -1) 53 | return 1; 54 | 55 | printf("NORMAL: "); 56 | print_addr(mbfd, MEM_FLAG_NORMAL); 57 | printf("DIRECT: "); 58 | print_addr(mbfd, MEM_FLAG_DIRECT); 59 | printf("COHERENT: "); 60 | print_addr(mbfd, MEM_FLAG_COHERENT); 61 | printf("L1_NONALLOCATING: "); 62 | print_addr(mbfd, MEM_FLAG_L1_NONALLOCATING); 63 | 64 | err = mailbox_close(mbfd); 65 | return err; 66 | } 67 | --------------------------------------------------------------------------------