2 * tag: simple function library
4 * Copyright (C) 2003 Stefan Reinauer
6 * See the file "COPYING" for further information about
7 * the copyright and warranty status of this work.
11 #include "libc/vsprintf.h"
12 #include "libopenbios/bindings.h"
14 #include "libopenbios/sys_info.h"
17 #include "arch/sparc64/ofmem_sparc64.h"
19 /* Format a string and print it on the screen, just like the libc
22 int printk( const char *fmt, ... )
29 i = vsnprintf(buf, sizeof(buf), fmt, args);
37 /* Private functions for mapping between physical/virtual addresses */
39 va2pa(unsigned long va)
41 if ((va >= (unsigned long)&_start) &&
42 (va < (unsigned long)&_end))
51 if ((pa + va_shift >= (unsigned long)&_start) &&
52 (pa + va_shift < (unsigned long)&_end))
58 void *malloc(int size)
60 return ofmem_malloc(size);
63 void* realloc( void *ptr, size_t size )
65 return ofmem_realloc(ptr, size);
84 void ofmem_walk_boot_map(translation_entry_cb cb)
86 unsigned long phys, virt, size, mode, data, mask;
89 for (i = 0; i < 64; i++) {
90 data = spitfire_get_dtlb_data(i);
91 if (data & SPITFIRE_TTE_VALID) {
92 switch ((data >> 61) & 3) {
95 mask = 0xffffffffffffe000ULL;
99 mask = 0xffffffffffff0000ULL;
100 size = PAGE_SIZE_64K;
103 mask = 0xfffffffffff80000ULL;
104 size = PAGE_SIZE_512K;
107 mask = 0xffffffffffc00000ULL;
112 virt = spitfire_get_dtlb_tag(i);
115 /* extract 41bit physical address */
116 phys = data & 0x000001fffffff000ULL;
121 cb(phys, virt, size, mode);
128 ( virt -- false | phys.lo ... phys.hi mode true )
138 phys = ofmem_translate(virt, &mode);
141 PUSH(phys & 0xffffffff);
152 * D5.3 pgmap@ ( va -- tte )
157 unsigned long va, tte_data;
161 tte_data = find_tte(va);
165 /* return tte_data */
170 /* If we get here, there was no entry */
175 ( index tte_data vaddr -- ? )
180 unsigned long vaddr, tte_data, idx;
185 dtlb_load3(vaddr, tte_data, idx);
188 /* MMU D-TLB miss handler */
190 dtlb_miss_handler(void)
192 unsigned long faultva, tte_data = 0;
194 /* Grab fault address from MMU and round to nearest 8k page */
195 faultva = dtlb_faultva();
199 /* If a valid va>tte-data routine has been set, invoke that Forth xt instead */
200 if (va2ttedata && *va2ttedata != 0) {
202 /* va>tte-data ( addr cnum -- false | tte-data true ) */
205 enterforth(*va2ttedata);
207 /* Check the result first... */
212 /* Grab the real data */
216 /* Search the ofmem linked list for this virtual address */
217 tte_data = find_tte(faultva);
222 dtlb_load2(faultva, tte_data);
224 /* If we got here, there was no translation so fail */
231 ( index tte_data vaddr -- ? )
236 unsigned long vaddr, tte_data, idx;
241 itlb_load3(vaddr, tte_data, idx);
244 /* MMU I-TLB miss handler */
246 itlb_miss_handler(void)
248 unsigned long faultva, tte_data = 0;
250 /* Grab fault address from MMU and round to nearest 8k page */
251 faultva = itlb_faultva();
255 /* If a valid va>tte-data routine has been set, invoke that Forth xt instead */
256 if (va2ttedata && *va2ttedata != 0) {
258 /* va>tte-data ( addr cnum -- false | tte-data true ) */
261 enterforth(*va2ttedata);
263 /* Check the result first... */
268 /* Grab the real data */
272 /* Search the ofmem linked list for this virtual address */
273 tte_data = find_tte(faultva);
278 itlb_load2(faultva, tte_data);
280 /* If we got here, there was no translation so fail */
287 ( phys.lo ... phys.hi virt size mode -- )
292 ucell virt, size, mode;
302 ofmem_map(phys, virt, size, mode);
316 ofmem_unmap(virt, size);
321 ( virt size align -- base )
326 ucell virt=-1UL, size, align;
334 virt = ofmem_claim_virt(virt, size, align);
351 ofmem_release_virt(virt, size);
354 /* ( phys size align --- base ) */
359 phys_addr_t phys=-1UL;
369 phys = ofmem_claim_phys(phys, size, align);
371 PUSH(phys & 0xffffffffUL);
375 /* ( phys size --- ) */
387 ofmem_release_phys(phys, size);
390 /* ( name-cstr phys size align --- phys ) */
395 phys_addr_t phys=-1UL;
405 /* Currently do nothing with the name */
408 phys = ofmem_retain(phys, size, align);
410 PUSH(phys & 0xffffffffUL);
414 /* ( virt size align -- baseaddr|-1 ) */
421 ucell ret = ofmem_claim( virt, size, align );
423 /* printk("ciface_claim: %08x %08x %x\n", virt, size, align ); */
427 /* ( virt size -- ) */
429 ciface_release( void )
433 ofmem_release(virt, size);
436 DECLARE_NODE(memory, INSTALL_OPEN, 0, "/memory");
438 NODE_METHODS( memory ) = {
439 { "claim", mem_claim },
440 { "release", mem_release },
441 { "SUNW,retain", mem_retain },
444 DECLARE_NODE(mmu, INSTALL_OPEN, 0, "/virtual-memory");
446 NODE_METHODS(mmu) = {
447 { "open", mmu_open },
448 { "close", mmu_close },
449 { "translate", mmu_translate },
450 { "SUNW,dtlb-load", dtlb_load },
451 { "SUNW,itlb-load", itlb_load },
453 { "unmap", mmu_unmap },
454 { "claim", mmu_claim },
455 { "release", mmu_release },
458 void ob_mmu_init(const char *cpuname, uint64_t ram_size)
461 REGISTER_NODE(memory);
466 ofmem_register(find_dev("/memory"), find_dev("/virtual-memory"));
469 fword("find-device");
471 push_str("/virtual-memory");
478 fword("find-device");
480 /* All memory: 0 to RAM_size */
486 PUSH((int)(ram_size >> 32));
489 PUSH((int)(ram_size & 0xffffffff));
495 push_str("/openprom/client-services");
496 fword("find-device");
497 bind_func("cif-claim", ciface_claim);
498 bind_func("cif-release", ciface_release);
500 /* Other MMU functions */
502 fword("active-package!");
503 bind_func("pgmap@", pgmap_fetch);
505 /* Find address of va2ttedata defer word contents for MMU miss handlers */
506 va2ttedata = (ucell *)findword("va>tte-data");