1/* 2 * Copyright (C) Paul Mackerras 1997. 3 * Copyright (C) Leigh Brown 2002. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 8 * 2 of the License, or (at your option) any later version. 9 */ 10 11#include "of1275.h" 12#include "nonstdio.h" 13 14/* 15 * Older OF's require that when claiming a specific range of addresses, 16 * we claim the physical space in the /memory node and the virtual 17 * space in the chosen mmu node, and then do a map operation to 18 * map virtual to physical. 19 */ 20static int need_map = -1; 21static ihandle chosen_mmu; 22static phandle memory; 23 24/* returns true if s2 is a prefix of s1 */ 25static int string_match(const char *s1, const char *s2) 26{ 27 for (; *s2; ++s2) 28 if (*s1++ != *s2) 29 return 0; 30 return 1; 31} 32 33static int check_of_version(void) 34{ 35 phandle oprom, chosen; 36 char version[64]; 37 38 oprom = finddevice("/openprom"); 39 if (oprom == OF_INVALID_HANDLE) 40 return 0; 41 if (getprop(oprom, "model", version, sizeof(version)) <= 0) 42 return 0; 43 version[sizeof(version)-1] = 0; 44 printf("OF version = '%s'\n", version); 45 if (!string_match(version, "Open Firmware, 1.") 46 && !string_match(version, "FirmWorks,3.")) 47 return 0; 48 chosen = finddevice("/chosen"); 49 if (chosen == OF_INVALID_HANDLE) { 50 chosen = finddevice("/chosen@0"); 51 if (chosen == OF_INVALID_HANDLE) { 52 printf("no chosen\n"); 53 return 0; 54 } 55 } 56 if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) { 57 printf("no mmu\n"); 58 return 0; 59 } 60 memory = (ihandle) call_prom("open", 1, 1, "/memory"); 61 if (memory == OF_INVALID_HANDLE) { 62 memory = (ihandle) call_prom("open", 1, 1, "/memory@0"); 63 if (memory == OF_INVALID_HANDLE) { 64 printf("no memory node\n"); 65 return 0; 66 } 67 } 68 printf("old OF detected\n"); 69 return 1; 70} 71 72void *claim(unsigned int virt, unsigned int size, unsigned int align) 73{ 74 int ret; 75 unsigned int result; 76 77 if (need_map < 0) 78 need_map = check_of_version(); 79 if (align || !need_map) 80 return (void *) call_prom("claim", 3, 1, virt, size, align); 81 82 ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory, 83 align, size, virt); 84 if (ret != 0 || result == -1) 85 return (void *) -1; 86 ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu, 87 align, size, virt); 88 /* 0x12 == coherent + read/write */ 89 ret = call_prom("call-method", 6, 1, "map", chosen_mmu, 90 0x12, size, virt, virt); 91 return virt; 92} 93