A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 120 lines 5.0 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2008 by Maurus Cuelenaere 11 * 12 * 32-bit MIPS threading support 13 * 14 * This program is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU General Public License 16 * as published by the Free Software Foundation; either version 2 17 * of the License, or (at your option) any later version. 18 * 19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20 * KIND, either express or implied. 21 * 22 ****************************************************************************/ 23 24/*--------------------------------------------------------------------------- 25 * Start the thread running and terminate it if it returns 26 *--------------------------------------------------------------------------- 27 */ 28 29void start_thread(void) USED_ATTR; /* Provide C access to ASM label */ 30static void USED_ATTR _start_thread(void) 31{ 32 /* t1 = context */ 33 asm volatile ( 34 "start_thread: \n" 35 ".set push \n" 36 ".set noreorder \n" 37 ".set noat \n" 38 "lw $8, 4($9) \n" /* Fetch thread function pointer ($8 = t0, $9 = t1) */ 39 "lw $29, 36($9) \n" /* Set initial sp(=$29) */ 40 "jalr $8 \n" /* Start the thread */ 41 "sw $0, 44($9) \n" /* Clear start address */ 42 ".set pop \n" 43 ); 44 thread_exit(); 45} 46 47/* Place context pointer in s0 slot, function pointer in s1 slot, and 48 * start_thread pointer in context_start */ 49#define THREAD_STARTUP_INIT(core, thread, function) \ 50 ({ (thread)->context.r[0] = (uint32_t)&(thread)->context, \ 51 (thread)->context.r[1] = (uint32_t)(function), \ 52 (thread)->context.start = (uint32_t)start_thread; }) 53 54/*--------------------------------------------------------------------------- 55 * Store non-volatile context. 56 *--------------------------------------------------------------------------- 57 */ 58static inline void store_context(void* addr) 59{ 60 asm volatile ( 61 ".set push \n" 62 ".set noreorder \n" 63 ".set noat \n" 64 "move $8, %0 \n" /* Store addr in clobbered t0 othrewise 65 * compiler could select %0 to be s0-s7 66 * during inlining which would break 67 * things horribly. 68 */ 69 "sw $16, 0($8) \n" /* s0 */ 70 "sw $17, 4($8) \n" /* s1 */ 71 "sw $18, 8($8) \n" /* s2 */ 72 "sw $19, 12($8) \n" /* s3 */ 73 "sw $20, 16($8) \n" /* s4 */ 74 "sw $21, 20($8) \n" /* s5 */ 75 "sw $22, 24($8) \n" /* s6 */ 76 "sw $23, 28($8) \n" /* s7 */ 77 "sw $30, 32($8) \n" /* fp */ 78 "sw $29, 36($8) \n" /* sp */ 79 "sw $31, 40($8) \n" /* ra */ 80 ".set pop \n" 81 : : "r" (addr) : "t0" 82 ); 83} 84 85/*--------------------------------------------------------------------------- 86 * Load non-volatile context. 87 *--------------------------------------------------------------------------- 88 */ 89static inline void load_context(const void* addr) 90{ 91 asm volatile ( 92 ".set push \n" 93 ".set noat \n" 94 ".set noreorder \n" 95 "lw $8, 44(%0) \n" /* Get start address ($8 = t0) */ 96 "beqz $8, running \n" /* NULL -> already running */ 97 "nop \n" 98 "jr $8 \n" 99 "move $9, %0 \n" /* t1 = context */ 100 "running: \n" 101 "move $8, %0 \n" /* Store addr in clobbered t0 otherwise 102 * compiler could select %0 to be s0-s7 103 * during inlining which would break 104 * things horribly. 105 */ 106 "lw $16, 0($8) \n" /* s0 */ 107 "lw $17, 4($8) \n" /* s1 */ 108 "lw $18, 8($8) \n" /* s2 */ 109 "lw $19, 12($8) \n" /* s3 */ 110 "lw $20, 16($8) \n" /* s4 */ 111 "lw $21, 20($8) \n" /* s5 */ 112 "lw $22, 24($8) \n" /* s6 */ 113 "lw $23, 28($8) \n" /* s7 */ 114 "lw $30, 32($8) \n" /* fp */ 115 "lw $29, 36($8) \n" /* sp */ 116 "lw $31, 40($8) \n" /* ra */ 117 ".set pop \n" 118 : : "r" (addr) : "t0", "t1" 119 ); 120}