1*8baf8813SIngo Weinhold /* 2*8baf8813SIngo Weinhold * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. 3*8baf8813SIngo Weinhold * Distributed under the terms of the MIT License. 4*8baf8813SIngo Weinhold * 5*8baf8813SIngo Weinhold * Copyright 2001, Travis Geiselbrecht. All rights reserved. 6*8baf8813SIngo Weinhold * Distributed under the terms of the NewOS License. 7*8baf8813SIngo Weinhold */ 8*8baf8813SIngo Weinhold 9*8baf8813SIngo Weinhold 10*8baf8813SIngo Weinhold #include <KernelExport.h> 11*8baf8813SIngo Weinhold 12*8baf8813SIngo Weinhold #include <arch_platform.h> 13*8baf8813SIngo Weinhold #include <arch/cpu.h> 14*8baf8813SIngo Weinhold #include <boot/kernel_args.h> 15*8baf8813SIngo Weinhold 16*8baf8813SIngo Weinhold 17*8baf8813SIngo Weinhold status_t 18*8baf8813SIngo Weinhold arch_cpu_preboot_init(kernel_args *args) 19*8baf8813SIngo Weinhold { 20*8baf8813SIngo Weinhold return B_OK; 21*8baf8813SIngo Weinhold } 22*8baf8813SIngo Weinhold 23*8baf8813SIngo Weinhold 24*8baf8813SIngo Weinhold status_t 25*8baf8813SIngo Weinhold arch_cpu_init(kernel_args *args) 26*8baf8813SIngo Weinhold { 27*8baf8813SIngo Weinhold return B_OK; 28*8baf8813SIngo Weinhold } 29*8baf8813SIngo Weinhold 30*8baf8813SIngo Weinhold 31*8baf8813SIngo Weinhold status_t 32*8baf8813SIngo Weinhold arch_cpu_init_post_vm(kernel_args *args) 33*8baf8813SIngo Weinhold { 34*8baf8813SIngo Weinhold return B_OK; 35*8baf8813SIngo Weinhold } 36*8baf8813SIngo Weinhold 37*8baf8813SIngo Weinhold status_t 38*8baf8813SIngo Weinhold arch_cpu_init_post_modules(kernel_args *args) 39*8baf8813SIngo Weinhold { 40*8baf8813SIngo Weinhold return B_OK; 41*8baf8813SIngo Weinhold } 42*8baf8813SIngo Weinhold 43*8baf8813SIngo Weinhold #define CACHELINE 32 44*8baf8813SIngo Weinhold 45*8baf8813SIngo Weinhold void 46*8baf8813SIngo Weinhold arch_cpu_sync_icache(void *address, size_t len) 47*8baf8813SIngo Weinhold { 48*8baf8813SIngo Weinhold int l, off; 49*8baf8813SIngo Weinhold char *p; 50*8baf8813SIngo Weinhold 51*8baf8813SIngo Weinhold off = (unsigned int)address & (CACHELINE - 1); 52*8baf8813SIngo Weinhold len += off; 53*8baf8813SIngo Weinhold 54*8baf8813SIngo Weinhold l = len; 55*8baf8813SIngo Weinhold p = (char *)address - off; 56*8baf8813SIngo Weinhold do { 57*8baf8813SIngo Weinhold asm volatile ("dcbst 0,%0" :: "r"(p)); 58*8baf8813SIngo Weinhold p += CACHELINE; 59*8baf8813SIngo Weinhold } while ((l -= CACHELINE) > 0); 60*8baf8813SIngo Weinhold asm volatile ("sync"); 61*8baf8813SIngo Weinhold 62*8baf8813SIngo Weinhold p = (char *)address - off; 63*8baf8813SIngo Weinhold do { 64*8baf8813SIngo Weinhold asm volatile ("icbi 0,%0" :: "r"(p)); 65*8baf8813SIngo Weinhold p += CACHELINE; 66*8baf8813SIngo Weinhold } while ((len -= CACHELINE) > 0); 67*8baf8813SIngo Weinhold asm volatile ("sync"); 68*8baf8813SIngo Weinhold isync(); 69*8baf8813SIngo Weinhold } 70*8baf8813SIngo Weinhold 71*8baf8813SIngo Weinhold 72*8baf8813SIngo Weinhold void 73*8baf8813SIngo Weinhold arch_cpu_invalidate_TLB_range(addr_t start, addr_t end) 74*8baf8813SIngo Weinhold { 75*8baf8813SIngo Weinhold asm volatile("sync"); 76*8baf8813SIngo Weinhold while (start < end) { 77*8baf8813SIngo Weinhold asm volatile("tlbie %0" :: "r" (start)); 78*8baf8813SIngo Weinhold asm volatile("eieio"); 79*8baf8813SIngo Weinhold asm volatile("sync"); 80*8baf8813SIngo Weinhold start += B_PAGE_SIZE; 81*8baf8813SIngo Weinhold } 82*8baf8813SIngo Weinhold asm volatile("tlbsync"); 83*8baf8813SIngo Weinhold asm volatile("sync"); 84*8baf8813SIngo Weinhold } 85*8baf8813SIngo Weinhold 86*8baf8813SIngo Weinhold 87*8baf8813SIngo Weinhold void 88*8baf8813SIngo Weinhold arch_cpu_invalidate_TLB_list(addr_t pages[], int num_pages) 89*8baf8813SIngo Weinhold { 90*8baf8813SIngo Weinhold int i; 91*8baf8813SIngo Weinhold 92*8baf8813SIngo Weinhold asm volatile("sync"); 93*8baf8813SIngo Weinhold for (i = 0; i < num_pages; i++) { 94*8baf8813SIngo Weinhold asm volatile("tlbie %0" :: "r" (pages[i])); 95*8baf8813SIngo Weinhold asm volatile("eieio"); 96*8baf8813SIngo Weinhold asm volatile("sync"); 97*8baf8813SIngo Weinhold } 98*8baf8813SIngo Weinhold asm volatile("tlbsync"); 99*8baf8813SIngo Weinhold asm volatile("sync"); 100*8baf8813SIngo Weinhold } 101*8baf8813SIngo Weinhold 102*8baf8813SIngo Weinhold 103*8baf8813SIngo Weinhold void 104*8baf8813SIngo Weinhold arch_cpu_global_TLB_invalidate(void) 105*8baf8813SIngo Weinhold { 106*8baf8813SIngo Weinhold ppc_sync(); 107*8baf8813SIngo Weinhold tlbia(); 108*8baf8813SIngo Weinhold ppc_sync(); 109*8baf8813SIngo Weinhold } 110*8baf8813SIngo Weinhold 111*8baf8813SIngo Weinhold 112*8baf8813SIngo Weinhold void 113*8baf8813SIngo Weinhold arch_cpu_user_TLB_invalidate(void) 114*8baf8813SIngo Weinhold { 115*8baf8813SIngo Weinhold ppc_sync(); 116*8baf8813SIngo Weinhold tlbia(); 117*8baf8813SIngo Weinhold ppc_sync(); 118*8baf8813SIngo Weinhold } 119*8baf8813SIngo Weinhold 120*8baf8813SIngo Weinhold 121*8baf8813SIngo Weinhold status_t 122*8baf8813SIngo Weinhold arch_cpu_user_memcpy(void *to, const void *from, size_t size, addr_t *fault_handler) 123*8baf8813SIngo Weinhold { 124*8baf8813SIngo Weinhold char *tmp = (char *)to; 125*8baf8813SIngo Weinhold char *s = (char *)from; 126*8baf8813SIngo Weinhold 127*8baf8813SIngo Weinhold *fault_handler = (addr_t)&&error; 128*8baf8813SIngo Weinhold 129*8baf8813SIngo Weinhold while (size--) 130*8baf8813SIngo Weinhold *tmp++ = *s++; 131*8baf8813SIngo Weinhold 132*8baf8813SIngo Weinhold *fault_handler = 0; 133*8baf8813SIngo Weinhold return 0; 134*8baf8813SIngo Weinhold 135*8baf8813SIngo Weinhold error: 136*8baf8813SIngo Weinhold *fault_handler = 0; 137*8baf8813SIngo Weinhold return B_BAD_ADDRESS; 138*8baf8813SIngo Weinhold } 139*8baf8813SIngo Weinhold 140*8baf8813SIngo Weinhold 141*8baf8813SIngo Weinhold /** \brief Copies at most (\a size - 1) characters from the string in \a from to 142*8baf8813SIngo Weinhold * the string in \a to, NULL-terminating the result. 143*8baf8813SIngo Weinhold * 144*8baf8813SIngo Weinhold * \param to Pointer to the destination C-string. 145*8baf8813SIngo Weinhold * \param from Pointer to the source C-string. 146*8baf8813SIngo Weinhold * \param size Size in bytes of the string buffer pointed to by \a to. 147*8baf8813SIngo Weinhold * 148*8baf8813SIngo Weinhold * \return strlen(\a from). 149*8baf8813SIngo Weinhold */ 150*8baf8813SIngo Weinhold 151*8baf8813SIngo Weinhold ssize_t 152*8baf8813SIngo Weinhold arch_cpu_user_strlcpy(char *to, const char *from, size_t size, addr_t *faultHandler) 153*8baf8813SIngo Weinhold { 154*8baf8813SIngo Weinhold int from_length = 0; 155*8baf8813SIngo Weinhold 156*8baf8813SIngo Weinhold *faultHandler = (addr_t)&&error; 157*8baf8813SIngo Weinhold 158*8baf8813SIngo Weinhold if (size > 0) { 159*8baf8813SIngo Weinhold to[--size] = '\0'; 160*8baf8813SIngo Weinhold // copy 161*8baf8813SIngo Weinhold for ( ; size; size--, from_length++, to++, from++) { 162*8baf8813SIngo Weinhold if ((*to = *from) == '\0') 163*8baf8813SIngo Weinhold break; 164*8baf8813SIngo Weinhold } 165*8baf8813SIngo Weinhold } 166*8baf8813SIngo Weinhold // count any leftover from chars 167*8baf8813SIngo Weinhold while (*from++ != '\0') 168*8baf8813SIngo Weinhold from_length++; 169*8baf8813SIngo Weinhold 170*8baf8813SIngo Weinhold *faultHandler = 0; 171*8baf8813SIngo Weinhold return from_length; 172*8baf8813SIngo Weinhold 173*8baf8813SIngo Weinhold error: 174*8baf8813SIngo Weinhold *faultHandler = 0; 175*8baf8813SIngo Weinhold return B_BAD_ADDRESS; 176*8baf8813SIngo Weinhold } 177*8baf8813SIngo Weinhold 178*8baf8813SIngo Weinhold 179*8baf8813SIngo Weinhold status_t 180*8baf8813SIngo Weinhold arch_cpu_user_memset(void *s, char c, size_t count, addr_t *fault_handler) 181*8baf8813SIngo Weinhold { 182*8baf8813SIngo Weinhold char *xs = (char *)s; 183*8baf8813SIngo Weinhold 184*8baf8813SIngo Weinhold *fault_handler = (addr_t)&&error; 185*8baf8813SIngo Weinhold 186*8baf8813SIngo Weinhold while (count--) 187*8baf8813SIngo Weinhold *xs++ = c; 188*8baf8813SIngo Weinhold 189*8baf8813SIngo Weinhold *fault_handler = 0; 190*8baf8813SIngo Weinhold return 0; 191*8baf8813SIngo Weinhold 192*8baf8813SIngo Weinhold error: 193*8baf8813SIngo Weinhold *fault_handler = 0; 194*8baf8813SIngo Weinhold return B_BAD_ADDRESS; 195*8baf8813SIngo Weinhold } 196*8baf8813SIngo Weinhold 197*8baf8813SIngo Weinhold 198*8baf8813SIngo Weinhold status_t 199*8baf8813SIngo Weinhold arch_cpu_shutdown(bool reboot) 200*8baf8813SIngo Weinhold { 201*8baf8813SIngo Weinhold PPCPlatform::Default()->ShutDown(reboot); 202*8baf8813SIngo Weinhold return B_ERROR; 203*8baf8813SIngo Weinhold } 204*8baf8813SIngo Weinhold 205*8baf8813SIngo Weinhold 206*8baf8813SIngo Weinhold void 207*8baf8813SIngo Weinhold arch_cpu_idle(void) 208*8baf8813SIngo Weinhold { 209*8baf8813SIngo Weinhold } 210*8baf8813SIngo Weinhold 211