|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: #include <ppc/machine_routines.h> ! 23: #include <ppc/exception.h> ! 24: #include <ppc/misc_protos.h> ! 25: #include <ppc/Firmware.h> ! 26: #include <vm/vm_page.h> ! 27: #include <ppc/pmap.h> ! 28: #include <ppc/proc_reg.h> ! 29: #include <kern/processor.h> ! 30: ! 31: boolean_t get_interrupts_enabled(void); ! 32: extern boolean_t set_interrupts_enabled(boolean_t); ! 33: ! 34: /* Map memory map IO space */ ! 35: vm_offset_t ! 36: ml_io_map( ! 37: vm_offset_t phys_addr, ! 38: vm_size_t size) ! 39: { ! 40: return(io_map(phys_addr,size)); ! 41: } ! 42: ! 43: /* static memory allocation */ ! 44: vm_offset_t ! 45: ml_static_malloc( ! 46: vm_size_t size) ! 47: { ! 48: extern vm_offset_t static_memory_end; ! 49: extern boolean_t pmap_initialized; ! 50: vm_offset_t vaddr; ! 51: ! 52: if (pmap_initialized) ! 53: return((vm_offset_t)NULL); ! 54: else { ! 55: vaddr = static_memory_end; ! 56: static_memory_end = round_page(vaddr+size); ! 57: return(vaddr); ! 58: } ! 59: } ! 60: ! 61: vm_offset_t ! 62: ml_static_ptovirt( ! 63: vm_offset_t paddr) ! 64: { ! 65: extern vm_offset_t static_memory_end; ! 66: vm_offset_t vaddr; ! 67: ! 68: /* Static memory is map V=R */ ! 69: vaddr = paddr; ! 70: if ( (vaddr < static_memory_end) && (pmap_extract(kernel_pmap, vaddr)==paddr) ) ! 71: return(vaddr); ! 72: else ! 73: return((vm_offset_t)NULL); ! 74: } ! 75: ! 76: void ! 77: ml_static_mfree( ! 78: vm_offset_t vaddr, ! 79: vm_size_t size) ! 80: { ! 81: vm_offset_t paddr_cur, vaddr_cur; ! 82: ! 83: for (vaddr_cur = round_page(vaddr); ! 84: vaddr_cur < trunc_page(vaddr+size); ! 85: vaddr_cur += PAGE_SIZE) { ! 86: paddr_cur = pmap_extract(kernel_pmap, vaddr_cur); ! 87: if (paddr_cur != (vm_offset_t)NULL) { ! 88: vm_page_wire_count--; ! 89: pmap_remove(kernel_pmap, vaddr_cur, vaddr_cur+PAGE_SIZE); ! 90: vm_page_create(paddr_cur,paddr_cur+PAGE_SIZE); ! 91: } ! 92: } ! 93: } ! 94: ! 95: /* virtual to physical on wired pages */ ! 96: vm_offset_t ml_vtophys( ! 97: vm_offset_t vaddr) ! 98: { ! 99: return(pmap_extract(kernel_pmap, vaddr)); ! 100: } ! 101: ! 102: /* Initialize Interrupts */ ! 103: void ml_install_interrupt_handler( ! 104: void *nub, ! 105: int source, ! 106: void *target, ! 107: IOInterruptHandler handler, ! 108: void *refCon) ! 109: { ! 110: int current_cpu; ! 111: boolean_t current_state; ! 112: ! 113: current_state = ml_get_interrupts_enabled(); ! 114: ! 115: current_cpu = cpu_number(); ! 116: per_proc_info[current_cpu].interrupt_nub = nub; ! 117: per_proc_info[current_cpu].interrupt_source = source; ! 118: per_proc_info[current_cpu].interrupt_target = target; ! 119: per_proc_info[current_cpu].interrupt_handler = handler; ! 120: per_proc_info[current_cpu].interrupt_refCon = refCon; ! 121: per_proc_info[current_cpu].get_interrupts_enabled ! 122: = get_interrupts_enabled; ! 123: per_proc_info[current_cpu].set_interrupts_enabled ! 124: = set_interrupts_enabled; ! 125: ! 126: (void) ml_set_interrupts_enabled(current_state); ! 127: } ! 128: ! 129: boolean_t fake_get_interrupts_enabled(void) ! 130: { ! 131: /* ! 132: * The scheduler is not active on this cpu. There is no need to disable ! 133: * preemption. The current thread wont be dispatched on anhother cpu. ! 134: */ ! 135: return(per_proc_info[cpu_number()].cpu_flags & turnEEon); ! 136: } ! 137: ! 138: boolean_t fake_set_interrupts_enabled(boolean_t enable) ! 139: { ! 140: boolean_t interrupt_state_prev; ! 141: ! 142: /* ! 143: * The scheduler is not active on this cpu. There is no need to disable ! 144: * preemption. The current thread wont be dispatched on anhother cpu. ! 145: */ ! 146: interrupt_state_prev = ! 147: (per_proc_info[cpu_number()].cpu_flags & turnEEon) != 0; ! 148: if (interrupt_state_prev != enable) ! 149: per_proc_info[cpu_number()].cpu_flags ^= turnEEon; ! 150: return(interrupt_state_prev); ! 151: } ! 152: ! 153: /* Get Interrupts Enabled */ ! 154: boolean_t ml_get_interrupts_enabled(void) ! 155: { ! 156: return(per_proc_info[cpu_number()].get_interrupts_enabled()); ! 157: } ! 158: ! 159: boolean_t get_interrupts_enabled(void) ! 160: { ! 161: return((mfmsr() & MASK(MSR_EE)) != 0); ! 162: } ! 163: ! 164: /* Set Interrupts Enabled */ ! 165: boolean_t ml_set_interrupts_enabled(boolean_t enable) ! 166: { ! 167: return(per_proc_info[cpu_number()].set_interrupts_enabled(enable)); ! 168: } ! 169: ! 170: /* Check if running at interrupt context */ ! 171: boolean_t ml_at_interrupt_context(void) ! 172: { ! 173: /* ! 174: * If running at interrupt context, the current thread won't be ! 175: * dispatched on another cpu. There is no need to turn off preemption. ! 176: */ ! 177: return (per_proc_info[cpu_number()].istackptr == 0); ! 178: } ! 179: ! 180: /* Generate a fake interrupt */ ! 181: void ml_cause_interrupt(void) ! 182: { ! 183: CreateFakeIO(); ! 184: } ! 185: ! 186: void machine_clock_assist(void) ! 187: { ! 188: if (per_proc_info[cpu_number()].get_interrupts_enabled == fake_get_interrupts_enabled) ! 189: CreateFakeDEC(); ! 190: } ! 191: ! 192: extern void cpu_signal_handler(void); ! 193: ! 194: kern_return_t ! 195: ml_processor_register( ! 196: cpu_id_t cpu_id, ! 197: vm_offset_t start_paddr, ! 198: processor_t *processor, ! 199: ipi_handler_t *ipi_handler, ! 200: boolean_t boot_cpu) ! 201: { ! 202: kern_return_t ret; ! 203: int target_cpu; ! 204: ! 205: if (boot_cpu == FALSE) { ! 206: if (cpu_register(&target_cpu) != KERN_SUCCESS) ! 207: return KERN_FAILURE; ! 208: } else { ! 209: /* boot_cpu is always 0 */ ! 210: target_cpu= 0; ! 211: } ! 212: ! 213: per_proc_info[target_cpu].cpu_id = cpu_id; ! 214: per_proc_info[target_cpu].start_paddr = start_paddr; ! 215: *processor = cpu_to_processor(target_cpu); ! 216: *ipi_handler = cpu_signal_handler; ! 217: ! 218: return KERN_SUCCESS; ! 219: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.