|
|
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.