A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 372 lines 12 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2002 by Alan Korr 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * KIND, either express or implied. 19 * 20 ****************************************************************************/ 21 22#ifndef __SYSTEM_H__ 23#define __SYSTEM_H__ 24 25#include <stdbool.h> 26#include <stdint.h> 27#include "cpu.h" 28#include "gcc_extensions.h" /* for LIKELY/UNLIKELY */ 29 30extern void system_reboot (void); 31/* Called from any UIE handler and panicf - wait for a key and return 32 * to reboot system. */ 33extern void system_exception_wait(void); 34 35#if NUM_CORES == 1 36extern void system_init(void) INIT_ATTR; 37#else 38/* TODO: probably safe to use INIT_ATTR on multicore but this needs checking */ 39extern void system_init(void); 40#endif 41 42extern long cpu_frequency; 43 44struct flash_header { 45 uint32_t magic; 46 uint32_t length; 47 char version[32]; 48}; 49 50bool detect_flashed_romimage(void); 51bool detect_flashed_ramimage(void); 52bool detect_original_firmware(void); 53 54#if defined(HAVE_ADJUSTABLE_CPU_FREQ) \ 55 && defined(ROCKBOX_HAS_LOGF) && (NUM_CORES == 1) 56#define CPU_BOOST_LOGGING 57#endif 58 59#ifdef HAVE_ADJUSTABLE_CPU_FREQ 60#define FREQ cpu_frequency 61void set_cpu_frequency(long frequency); 62#ifdef CPU_BOOST_LOGGING 63char * cpu_boost_log_getlog_first(void); 64char * cpu_boost_log_getlog_next(void); 65int cpu_boost_log_getcount(void); 66void cpu_boost_(bool on_off, char* location, int line); 67#else 68void cpu_boost(bool on_off); 69#endif 70void cpu_idle_mode(bool on_off); 71int get_cpu_boost_counter(void); 72#else /* ndef HAVE_ADJUSTABLE_CPU_FREQ */ 73#ifndef FREQ 74#define FREQ CPU_FREQ 75#endif 76#define set_cpu_frequency(frequency) 77#define cpu_boost(on_off) 78#define cpu_boost_id(on_off, id) 79#define cpu_idle_mode(on_off) 80#define get_cpu_boost_counter() 81#define get_cpu_boost_tracker() 82#endif /* HAVE_ADJUSTABLE_CPU_FREQ */ 83 84#ifdef CPU_BOOST_LOGGING 85#define cpu_boost(on_off) cpu_boost_(on_off,__FILE__, __LINE__) 86#endif 87 88#define BAUDRATE 9600 89 90/* wrap-safe macros for tick comparison */ 91#define TIME_AFTER(a,b) ((long)(b) - (long)(a) < 0) 92#define TIME_BEFORE(a,b) TIME_AFTER(b,a) 93 94#ifndef NULL 95#define NULL ((void*)0) 96#endif 97 98#ifndef MIN 99#define MIN(a, b) (((a)<(b))?(a):(b)) 100#endif 101 102#ifndef MAX 103#define MAX(a, b) (((a)>(b))?(a):(b)) 104#endif 105 106#ifndef SGN 107#define SGN(a) \ 108 ({ typeof (a) ___a = (a); (___a > 0) - (___a < 0); }) 109#endif 110 111/* return number of elements in array a */ 112#define ARRAYLEN(a) (sizeof(a)/sizeof((a)[0])) 113 114/* is the given pointer "p" inside the said bounds of array "a"? */ 115#define PTR_IN_ARRAY(a, p, numelem) \ 116 ((uintptr_t)(p) - (uintptr_t)(a) < (uintptr_t)(numelem)*sizeof ((a)[0])) 117 118/* return p incremented by specified number of bytes */ 119#define SKIPBYTES(p, count) ((typeof (p))((char *)(p) + (count))) 120 121#define P2_M1(p2) ((1 << (p2))-1) 122 123/* align up or down to nearest 2^p2 */ 124#define ALIGN_DOWN_P2(n, p2) ((n) & ~P2_M1(p2)) 125#define ALIGN_UP_P2(n, p2) ALIGN_DOWN_P2((n) + P2_M1(p2),p2) 126 127/* align up or down to nearest integer multiple of a */ 128#define ALIGN_DOWN(n, a) ((typeof(n))((uintptr_t)(n)/(a)*(a))) 129#define ALIGN_UP(n, a) ALIGN_DOWN((n)+((a)-1),a) 130 131/* align start and end of buffer to nearest integer multiple of a */ 132#define ALIGN_BUFFER(ptr, size, align) \ 133({ \ 134 size_t __sz = (size); \ 135 size_t __ali = (align); \ 136 uintptr_t __a1 = (uintptr_t)(ptr); \ 137 uintptr_t __a2 = __a1 + __sz; \ 138 __a1 = ALIGN_UP(__a1, __ali); \ 139 __a2 = ALIGN_DOWN(__a2, __ali); \ 140 (ptr) = (typeof (ptr))__a1; \ 141 (size) = __a2 > __a1 ? __a2 - __a1 : 0; \ 142}) 143 144#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) 145 146#define PTR_ADD(ptr, x) ((typeof(ptr))((char*)(ptr) + (x))) 147#define PTR_SUB(ptr, x) ((typeof(ptr))((char*)(ptr) - (x))) 148 149#ifndef alignof 150#define alignof __alignof__ 151#endif 152 153/* Get the byte offset of a type's member */ 154#ifndef offsetof 155#define offsetof(type, member) __builtin_offsetof(type, member) 156#endif 157 158/* Get the containing item of *ptr in type */ 159#ifndef container_of 160#define container_of(ptr, type, member) ({ \ 161 const typeof (((type *)0)->member) *__mptr = (ptr); \ 162 (type *)((void *)(__mptr) - offsetof(type, member)); }) 163#endif 164 165/* returns index of first set bit or 32 if no bits are set */ 166#if defined(CPU_ARM) && ARM_ARCH >= 5 && !defined(__thumb__) 167static inline int find_first_set_bit(uint32_t val) 168 { return LIKELY(val) ? __builtin_ctz(val) : 32; } 169#else 170int find_first_set_bit(uint32_t val); 171#endif 172 173static inline __attribute__((always_inline)) 174uint32_t isolate_first_bit(uint32_t val) 175 { return val & -val; } 176 177/* Functions to set and clear register or variable bits atomically; 178 * return value is the previous value of *addr */ 179uint16_t bitmod16(volatile uint16_t *addr, uint16_t bits, uint16_t mask); 180uint16_t bitset16(volatile uint16_t *addr, uint16_t mask); 181uint16_t bitclr16(volatile uint16_t *addr, uint16_t mask); 182 183uint32_t bitmod32(volatile uint32_t *addr, uint32_t bits, uint32_t mask); 184uint32_t bitset32(volatile uint32_t *addr, uint32_t mask); 185uint32_t bitclr32(volatile uint32_t *addr, uint32_t mask); 186 187/* gcc 3.4 changed the format of the constraints */ 188#if (__GNUC__ >= 3) && (__GNUC_MINOR__ > 3) || (__GNUC__ >= 4) 189#define I_CONSTRAINT "I08" 190#else 191#define I_CONSTRAINT "I" 192#endif 193 194/* Utilize the user break controller to catch invalid memory accesses. */ 195int system_memory_guard(int newmode); 196 197enum { 198 MEMGUARD_KEEP = -1, /* don't change the mode; for reading */ 199 MEMGUARD_NONE = 0, /* catch nothing */ 200 MEMGUARD_FLASH_WRITES, /* catch writes to area 02 (flash ROM) */ 201 MEMGUARD_ZERO_AREA, /* catch all accesses to areas 00 and 01 */ 202 MAXMEMGUARD 203}; 204 205#if !defined(SIMULATOR) && !defined(__PCTOOL__) 206#include "system-target.h" 207#elif defined(HAVE_SDL) /* SDL build */ 208#include "system-sdl.h" 209#ifdef SIMULATOR 210#include "system-sim.h" 211#endif 212#elif defined(__PCTOOL__) 213#include "system-hosted.h" 214#endif 215 216#include "bitswap.h" 217#include "rbendian.h" 218 219#ifndef ASSERT_CPU_MODE 220/* Very useful to have defined properly for your architecture */ 221#define ASSERT_CPU_MODE(mode, rstatus...) \ 222 ({ (void)(mode); rstatus; }) 223#endif 224 225#ifndef CPU_MODE_THREAD_CONTEXT 226#define CPU_MODE_THREAD_CONTEXT 0 227#endif 228 229#ifdef HAVE_ADJUSTABLE_CPU_FREQ 230#ifndef CPU_BOOST_LOCK_DEFINED 231#define CPU_BOOST_LOCK_DEFINED 232/* Compatibility defauls */ 233static inline bool cpu_boost_lock(void) 234 { return true; } 235static inline void cpu_boost_unlock(void) 236 { } 237#endif /* CPU_BOOST_LOCK */ 238#endif /* HAVE_ADJUSTABLE_CPU_FREQ */ 239 240#ifndef BIT_N 241#define BIT_N(n) (1U << (n)) 242#endif 243 244#ifndef MASK_N 245/* Make a mask of n contiguous bits, shifted left by 'shift' */ 246#define MASK_N(type, n, shift) \ 247 ((type)((((type)1 << (n)) - (type)1) << (shift))) 248#endif 249 250/* Declare this as HIGHEST_IRQ_LEVEL if they don't differ */ 251#ifndef DISABLE_INTERRUPTS 252#define DISABLE_INTERRUPTS HIGHEST_IRQ_LEVEL 253#endif 254 255/* Define this, if the CPU may take advantage of cache aligment. Is enabled 256 * for all ARM CPUs. */ 257#ifdef CPU_ARM 258 #define HAVE_CPU_CACHE_ALIGN 259 #define MIN_STACK_ALIGN 8 260#endif 261 262#ifdef CPU_MIPS 263 #define HAVE_CPU_CACHE_ALIGN 264#endif 265 266/* Define this if target has support for generating backtraces */ 267#if defined(CPU_ARM) || \ 268 (defined(CPU_MIPS) && (CONFIG_PLATFORM & PLATFORM_NATIVE)) 269#ifndef DISABLE_BACKTRACE 270 #define HAVE_RB_BACKTRACE 271#endif 272#endif 273 274#ifndef MIN_STACK_ALIGN 275#define MIN_STACK_ALIGN (sizeof (uintptr_t)) 276#endif 277 278/* Calculate CACHEALIGN_SIZE from CACHEALIGN_BITS */ 279#ifdef CACHEALIGN_SIZE 280 /* undefine, if defined. always calculate from CACHEALIGN_BITS */ 281 #undef CACHEALIGN_SIZE 282#endif 283#ifdef CACHEALIGN_BITS 284 /* CACHEALIGN_SIZE = 2 ^ CACHEALIGN_BITS */ 285 #define CACHEALIGN_SIZE (1u << CACHEALIGN_BITS) 286#else 287 /* FIXME: set to maximum known cache alignment of supported CPUs */ 288 #define CACHEALIGN_BITS 5 289 #define CACHEALIGN_SIZE 32 290#endif 291 292#ifdef HAVE_CPU_CACHE_ALIGN 293 /* Cache alignment attributes and sizes are enabled */ 294 #define CACHEALIGN_ATTR __attribute__((aligned(CACHEALIGN_SIZE))) 295 /* Aligns x up to a CACHEALIGN_SIZE boundary */ 296 #define CACHEALIGN_UP(x) \ 297 ((typeof (x))ALIGN_UP_P2((uintptr_t)(x), CACHEALIGN_BITS)) 298 /* Aligns x down to a CACHEALIGN_SIZE boundary */ 299 #define CACHEALIGN_DOWN(x) \ 300 ((typeof (x))ALIGN_DOWN_P2((uintptr_t)(x), CACHEALIGN_BITS)) 301 /* Aligns at least to the greater of size x or CACHEALIGN_SIZE */ 302 #define CACHEALIGN_AT_LEAST_ATTR(x) \ 303 __attribute__((aligned(CACHEALIGN_UP(x)))) 304 /* Aligns a buffer pointer and size to proper boundaries */ 305 #define CACHEALIGN_BUFFER(start, size) \ 306 ALIGN_BUFFER((start), (size), CACHEALIGN_SIZE) 307#else 308 /* Cache alignment attributes and sizes are not enabled */ 309 #define CACHEALIGN_ATTR 310 #define CACHEALIGN_AT_LEAST_ATTR(x) __attribute__((aligned(x))) 311 #define CACHEALIGN_UP(x) (x) 312 #define CACHEALIGN_DOWN(x) (x) 313 /* Make no adjustments */ 314 #define CACHEALIGN_BUFFER(start, size) 315#endif 316 317/* Define MEM_ALIGN_ATTR which may be used to align e.g. buffers for faster 318 * access. */ 319#if defined(HAVE_CPU_CACHE_ALIGN) 320 /* Align to a cache line. */ 321 #define MEM_ALIGN_ATTR CACHEALIGN_ATTR 322 #define MEM_ALIGN_SIZE CACHEALIGN_SIZE 323#elif defined(CPU_COLDFIRE) 324 /* Use fixed alignment of 16 bytes. Speed up only for 'movem' in DRAM. */ 325 #define MEM_ALIGN_ATTR __attribute__((aligned(16))) 326 #define MEM_ALIGN_SIZE 16 327#else 328 /* Align pointer size */ 329 #define MEM_ALIGN_ATTR __attribute__((aligned(sizeof(intptr_t)))) 330 #define MEM_ALIGN_SIZE sizeof(intptr_t) 331#endif 332 333#define MEM_ALIGN_UP(x) \ 334 ((typeof (x))ALIGN_UP((uintptr_t)(x), MEM_ALIGN_SIZE)) 335#define MEM_ALIGN_DOWN(x) \ 336 ((typeof (x))ALIGN_DOWN((uintptr_t)(x), MEM_ALIGN_SIZE)) 337 338/* Bounce buffers may have alignment requirments */ 339#if defined(MAX_PHYS_SECTOR_SIZE) && !defined(STORAGE_WANTS_ALIGN) 340#define STORAGE_WANTS_ALIGN 341#endif 342 343#ifdef STORAGE_WANTS_ALIGN 344 #define STORAGE_ALIGN_ATTR __attribute__((aligned(CACHEALIGN_SIZE))) 345 #define STORAGE_ALIGN_DOWN(x) \ 346 ((typeof (x))ALIGN_DOWN_P2((uintptr_t)(x), CACHEALIGN_BITS)) 347 /* Pad a size so the buffer can be aligned later */ 348 #define STORAGE_PAD(x) ((x) + CACHEALIGN_SIZE - 1) 349 /* Number of bytes in the last cacheline assuming buffer of size x is aligned */ 350 #define STORAGE_OVERLAP(x) ((x) & (CACHEALIGN_SIZE - 1)) 351 #define STORAGE_ALIGN_BUFFER(start, size) \ 352 ALIGN_BUFFER((start), (size), CACHEALIGN_SIZE) 353#else 354 #define STORAGE_ALIGN_ATTR 355 #define STORAGE_ALIGN_DOWN(x) (x) 356 #define STORAGE_PAD(x) (x) 357 #define STORAGE_OVERLAP(x) 0 358 #define STORAGE_ALIGN_BUFFER(start, size) 359#endif 360 361/* Double-cast to avoid 'dereferencing type-punned pointer will 362 * break strict aliasing rules' B.S. */ 363#define PUN_PTR(type, p) ((type)(intptr_t)(p)) 364 365#ifndef SIMULATOR 366bool dbg_ports(void); 367#endif 368#if (CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SONY_NWZ_LINUX) || defined(HIBY_LINUX) || defined(FIIO_M3K_LINUX) 369bool dbg_hw_info(void); 370#endif 371 372#endif /* __SYSTEM_H__ */