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