/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2007 by Jens Arnold * Based on the work of Alan Korr and others * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #ifndef SYSTEM_TARGET_H #define SYSTEM_TARGET_H #define or_b(mask, address) \ asm \ ("or.b %0,@(r0,gbr)" \ : \ : /* %0 */ I_CONSTRAINT((char)(mask)), \ /* %1 */ "z"(address-GBR)) #define and_b(mask, address) \ asm \ ("and.b %0,@(r0,gbr)" \ : \ : /* %0 */ I_CONSTRAINT((char)(mask)), \ /* %1 */ "z"(address-GBR)) #define xor_b(mask, address) \ asm \ ("xor.b %0,@(r0,gbr)" \ : \ : /* %0 */ I_CONSTRAINT((char)(mask)), \ /* %1 */ "z"(address-GBR)) /**************************************************************************** * Interrupt level setting * The level is left shifted 4 bits ****************************************************************************/ #define HIGHEST_IRQ_LEVEL (15<<4) static inline int set_irq_level(int level) { int i; /* Read the old level and set the new one */ /* Not volatile - will be optimized away if the return value isn't used */ asm ("stc sr, %0" : "=r" (i)); asm volatile ("ldc %0, sr" : : "r" (level)); return i; } static inline void enable_irq(void) { int i; asm volatile ("mov %1, %0 \n" /* Save a constant load from RAM */ "ldc %0, sr \n" : "=&r"(i) : "i"(0)); } #define disable_irq() \ ((void)set_irq_level(HIGHEST_IRQ_LEVEL)) #define disable_irq_save() \ set_irq_level(HIGHEST_IRQ_LEVEL) #define restore_irq(i) \ ((void)set_irq_level(i)) static inline uint16_t swap16_hw(uint16_t value) /* result[15..8] = value[ 7..0]; result[ 7..0] = value[15..8]; */ { uint16_t result; asm ("swap.b\t%1,%0" : "=r"(result) : "r"(value)); return result; } static inline uint32_t swaw32_hw(uint32_t value) /* result[31..16] = value[15.. 0]; result[15.. 0] = value[31..16]; */ { uint32_t result; asm ("swap.w\t%1,%0" : "=r"(result) : "r"(value)); return result; } static inline uint32_t swap32_hw(uint32_t value) /* result[31..24] = value[ 7.. 0]; result[23..16] = value[15.. 8]; result[15.. 8] = value[23..16]; result[ 7.. 0] = value[31..24]; */ { asm ("swap.b\t%0,%0\n" "swap.w\t%0,%0\n" "swap.b\t%0,%0\n" : "+r"(value)); return value; } static inline uint32_t swap_odd_even32_hw(uint32_t value) { /* result[31..24],[15.. 8] = value[23..16],[ 7.. 0] result[23..16],[ 7.. 0] = value[31..24],[15.. 8] */ asm ("swap.b\t%0,%0\n" "swap.w\t%0,%0\n" "swap.b\t%0,%0\n" "swap.w\t%0,%0\n" : "+r"(value)); return value; } extern const unsigned bit_n_table[32]; #define BIT_N(n) ( \ __builtin_constant_p(n) \ ? (1U << (n)) \ : bit_n_table[n] \ ) static inline void commit_dcache(void) {} static inline void commit_discard_dcache(void) {} static inline void commit_discard_idcache(void) {} /*--------------------------------------------------------------------------- * Put core in a power-saving state. *--------------------------------------------------------------------------- */ static inline void core_sleep(void) { asm volatile ( "and.b #0x7f, @(r0, gbr) \n" /* Clear SBY (bit 7) in SBYCR */ "mov #0, r1 \n" /* Enable interrupts */ "ldc r1, sr \n" /* Following instruction cannot be interrupted */ "sleep \n" /* Execute standby */ : : "z"(&SBYCR-GBR) : "r1"); } #endif /* SYSTEM_TARGET_H */