bootmii_ppc.h

Go to the documentation of this file.
00001 /*
00002         libbroadway - A general purpose library to control the Wii.
00003         PowerPC helper functions
00004 
00005 Copyright (C) 2008              Segher Boessenkool <segher@kernel.crashing.org>
00006 Copyright (C) 2010              Alex Marshall <trap15@raidenii.net>
00007 
00008 # This code is licensed to you under the terms of the GNU GPL, version 2;
00009 # see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
00010 */
00011 
00016 #ifndef __BOOTMII_PPC_H__
00017 #define __BOOTMII_PPC_H__
00018 
00019 #include <types.h>
00020 #include <broadway/hollywood.h>
00021 
00022 /* Broadway SPRs */
00023 #define SPR_XER         (   1)  
00024 #define SPR_LR          (   8)  
00025 #define SPR_CTR         (   9)  
00026 #define SPR_DSISR       (  18)  
00027 #define SPR_DAR         (  19)  
00028 #define SPR_DEC         (  22)  
00029 #define SPR_SDR1        (  25)  
00030 #define SPR_SRR0        (  26)  
00031 #define SPR_SRR1        (  27)  
00032 #define SPR_SPRG0       ( 272)  
00033 #define SPR_SPRG1       ( 273)  
00034 #define SPR_SPRG2       ( 274)  
00035 #define SPR_SPRG3       ( 275)  
00036 #define SPR_EAR         ( 282)  
00037 #define SPR_PVR         ( 287)  
00038 #define SPR_IBAT0U      ( 528)  
00039 #define SPR_IBAT0L      ( 529)  
00040 #define SPR_IBAT1U      ( 530)  
00041 #define SPR_IBAT1L      ( 531)  
00042 #define SPR_IBAT2U      ( 532)  
00043 #define SPR_IBAT2L      ( 533)  
00044 #define SPR_IBAT3U      ( 534)  
00045 #define SPR_IBAT3L      ( 535)  
00046 #define SPR_DBAT0U      ( 536)  
00047 #define SPR_DBAT0L      ( 537)  
00048 #define SPR_DBAT1U      ( 538)  
00049 #define SPR_DBAT1L      ( 539)  
00050 #define SPR_DBAT2U      ( 540)  
00051 #define SPR_DBAT2L      ( 541)  
00052 #define SPR_DBAT3U      ( 542)  
00053 #define SPR_DBAT3L      ( 543)  
00054 #define SPR_GQR0        ( 912)  
00055 #define SPR_GQR1        ( 913)  
00056 #define SPR_GQR2        ( 914)  
00057 #define SPR_GQR3        ( 915)  
00058 #define SPR_GQR4        ( 916)  
00059 #define SPR_GQR5        ( 917)  
00060 #define SPR_GQR6        ( 918)  
00061 #define SPR_GQR7        ( 919)  
00062 #define SPR_HID2        ( 920)  
00063 #define SPR_WPAR        ( 921)  
00064 #define SPR_DMA_U       ( 922)  
00065 #define SPR_DMA_L       ( 923)  
00066 #define SPR_UMMCR0      ( 936)  
00067 #define SPR_UPMC1       ( 937)  
00068 #define SPR_UPMC2       ( 938)  
00069 #define SPR_USIA        ( 939)  
00070 #define SPR_UMMCR1      ( 940)  
00071 #define SPR_UPMC3       ( 941)  
00072 #define SPR_UPMC4       ( 942)  
00073 #define SPR_USDA        ( 943)  
00074 #define SPR_MMCR0       ( 952)  
00075 #define SPR_PMC1        ( 953)  
00076 #define SPR_PMC2        ( 954)  
00077 #define SPR_SIA         ( 955)  
00078 #define SPR_MMCR1       ( 956)  
00079 #define SPR_PMC3        ( 957)  
00080 #define SPR_PMC4        ( 958)  
00081 #define SPR_SDA         ( 959)  
00082 #define SPR_HID0        (1008)  
00083 #define SPR_HID1        (1009)  
00084 #define SPR_IABR        (1010)  
00085 #define SPR_HID4        (1011)  
00086 #define SPR_DABR        (1013)  
00087 #define SPR_L2CR        (1017)  
00088 #define SPR_ICTC        (1019)  
00089 #define SPR_THRM1       (1020)  
00090 #define SPR_THRM2       (1021)  
00091 #define SPR_THRM3       (1022)  
00094 #define MEM2_BSS        __attribute__ ((section (".bss.mem2")))         
00095 #define MEM2_DATA       __attribute__ ((section (".data.mem2")))        
00096 #define MEM2_RODATA     __attribute__ ((section (".rodata.mem2")))      
00097 #define ALIGNED(x)      __attribute__ ((aligned(x)))
00098 
00107 #define STACK_ALIGN(type, name, cnt, alignment)         \
00108         u8 _al__##name[((sizeof(type)*(cnt)) + (alignment) + \
00109         (((sizeof(type)*(cnt))%(alignment)) > 0 ? ((alignment) - \
00110         ((sizeof(type)*(cnt))%(alignment))) : 0))]; \
00111         type *name = (type*)(((u32)(_al__##name)) + ((alignment) - (( \
00112         (u32)(_al__##name))&((alignment)-1))))
00113 
00114 #define VIRT_TO_PHYS(x)         ((u32)(x) & 0x3FFFFFFF) 
00115 #define PHYS_TO_VIRT(x)         ((u32)(x) | 0x80000000) 
00116 #define PHYS_TO_VIRT_NOCACHE(x) ((u32)(x) | 0xC0000000) 
00118 /* Basic I/O. */
00119 
00125 static inline u32 read32(u32 addr)
00126 {
00127         u32 x;
00128         asm volatile("lwz %0,0(%1) ; sync" : "=r"(x) : "b"(PHYS_TO_VIRT_NOCACHE(addr)));
00129         return x;
00130 }
00131 
00138 static inline void write32(u32 addr, u32 x)
00139 {
00140         asm("stw %0,0(%1) ; eieio" : : "r"(x), "b"(PHYS_TO_VIRT_NOCACHE(addr)));
00141 }
00142 
00149 static inline void set32(u32 addr, u32 set)
00150 {
00151         write32(addr, read32(addr) | set);
00152 }
00153 
00160 static inline void clear32(u32 addr, u32 clear)
00161 {
00162         write32(addr, read32(addr) & (~clear));
00163 }
00164 
00171 static inline void flip32(u32 addr, u32 flip)
00172 {
00173         write32(addr, read32(addr) ^ flip);
00174 }
00175 
00183 static inline void mask32(u32 addr, u32 clear, u32 set)
00184 {
00185         write32(addr, (read32(addr) & (~clear)) | set);
00186 }
00187 
00194 static inline u16 read16(u32 addr)
00195 {
00196         u16 x;
00197         asm volatile("lhz %0,0(%1) ; sync" : "=r"(x) : "b"(PHYS_TO_VIRT_NOCACHE(addr)));
00198         return x;
00199 }
00200 
00207 static inline void write16(u32 addr, u16 x)
00208 {
00209         asm("sth %0,0(%1) ; eieio" : : "r"(x), "b"(PHYS_TO_VIRT_NOCACHE(addr)));
00210 }
00211 
00218 static inline void set16(u32 addr, u16 set)
00219 {
00220         write16(addr, read16(addr) | set);
00221 }
00222 
00229 static inline void clear16(u32 addr, u16 clear)
00230 {
00231         write16(addr, read16(addr) & (~clear));
00232 }
00233 
00240 static inline void flip16(u32 addr, u16 flip)
00241 {
00242         write16(addr, read16(addr) ^ flip);
00243 }
00244 
00252 static inline void mask16(u32 addr, u16 clear, u16 set)
00253 {
00254         write16(addr, (read16(addr) & (~clear)) | set);
00255 }
00256 
00263 static inline u8 read8(u32 addr)
00264 {
00265         u8 x;
00266         asm volatile("lbz %0,0(%1) ; sync" : "=r"(x) : "b"(PHYS_TO_VIRT_NOCACHE(addr)));
00267         return x;
00268 }
00269 
00276 static inline void write8(u32 addr, u8 x)
00277 {
00278         asm("stb %0,0(%1) ; eieio" : : "r"(x), "b"(PHYS_TO_VIRT_NOCACHE(addr)));
00279 }
00280 
00287 static inline void set8(u32 addr, u8 set)
00288 {
00289         write8(addr, read8(addr) | set);
00290 }
00291 
00298 static inline void clear8(u32 addr, u8 clear)
00299 {
00300         write8(addr, read8(addr) & (~clear));
00301 }
00302 
00309 static inline void flip8(u32 addr, u8 flip)
00310 {
00311         write8(addr, read8(addr) ^ flip);
00312 }
00313 
00321 static inline void mask8(u32 addr, u8 clear, u8 set)
00322 {
00323         write8(addr, (read8(addr) & (~clear)) | set);
00324 }
00325 
00326 /* Address mapping. */
00332 static inline u32 virt_to_phys(const void *p)
00333 {
00334         return (u32)(VIRT_TO_PHYS(p));
00335 }
00336 
00342 static inline void *phys_to_virt(u32 x)
00343 {
00344         return (void *)(PHYS_TO_VIRT(x));
00345 }
00346 
00352 static inline void *phys_to_virt_nocache(u32 x)
00353 {
00354         return (void *)(PHYS_TO_VIRT_NOCACHE(x));
00355 }
00356 
00357 /* Cache synchronisation. */
00363 void sync_before_read(void *p, u32 len);
00369 void flush_after_write(void *p, u32 len);
00375 void sync_after_write(const void *p, u32 len);
00381 void sync_before_exec(const void *p, u32 len);
00384 void ppcsync(void);
00385 
00386 /* Time. */
00391 void udelay(u32 us);
00396 u64 getticks();
00401 void tickdelay(u64 ticks);
00402 #define usleep(n)       udelay(n)       
00403 #define mftb()          getticks()      
00405 /* Special purpose registers. */
00406 
00412 #define mtspr(n, x) asm("mtspr %1,%0" : : "r"(x), "i"(n))
00413 
00419 #define mfspr(n) ({ \
00420         u32 x; asm volatile("mfspr %0,%1" : "=r"(x) : "i"(n)); x; \
00421 })
00422 
00423 /* Exceptions. */
00426 void exception_init(void);
00429 typedef void (*except_handler)(int exception);
00431 extern volatile except_handler exception_handler_table[0x10];
00432 
00434 #define reboot()                write32(HW_RESETS, 0)
00435 
00436 #define hollywood_version()     ((read32(HW_VERSION) >> 4) & 0xF)
00437 
00438 #define hollywood_revision()    ((read32(HW_VERSION) >> 0) & 0xF)
00439 
00445 static inline void doze_mode()
00446 {
00447         u32 hid0;
00448         asm volatile("mfspr %0,1008" : "=r"(hid0));
00449         /* Disable sleep, nap and doze bits */
00450         hid0 &= ~(7 << 21);
00451         /* Enable doze bit */
00452         hid0 |= (1 << 23);
00453         asm volatile("mtspr 1008,%0" : : "r"(hid0));
00454 }
00455 
00461 static inline void nap_mode()
00462 {
00463         /* HID0 */
00464         u32 hid0;
00465         asm volatile("mfspr %0,1008" : "=r"(hid0));
00466         /* Disable sleep, nap and doze bits */
00467         hid0 &= ~(7 << 21);
00468         /* Enable nap bit */
00469         hid0 |= (1 << 22);
00470         asm volatile("mtspr 1008,%0" : : "r"(hid0));
00471 }
00472 
00478 static inline void sleep_mode()
00479 {
00480         /* HID0 */
00481         u32 hid0;
00482         asm volatile("mfspr %0,1008" : "=r"(hid0));
00483         /* Disable sleep, nap and doze bits */
00484         hid0 &= ~(7 << 21);
00485         /* Enable sleep bit */
00486         hid0 |= (1 << 21);
00487         asm volatile("mtspr 1008,%0" : : "r"(hid0));
00488 }
00489 
00495 static inline void power_save()
00496 {
00497         /* Switch to power-save mode */
00498         asm volatile(
00499                 "mfmsr  0               \n"
00500                 "oris   0, 0, 0x80      \n"
00501                 "sync                   \n"
00502                 "mtmsr  0               \n"
00503                 "isync                  \n"
00504                 : : : "0");
00505 }
00506 
00507 #endif
00508 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines
Generated by  doxygen 1.6.3