18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * init.c: PROM library initialisation code. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 1998 Harald Koerfgen 68c2ecf20Sopenharmony_ci * Copyright (C) 2002, 2004 Maciej W. Rozycki 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci#include <linux/init.h> 98c2ecf20Sopenharmony_ci#include <linux/kernel.h> 108c2ecf20Sopenharmony_ci#include <linux/linkage.h> 118c2ecf20Sopenharmony_ci#include <linux/smp.h> 128c2ecf20Sopenharmony_ci#include <linux/string.h> 138c2ecf20Sopenharmony_ci#include <linux/types.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <asm/bootinfo.h> 168c2ecf20Sopenharmony_ci#include <asm/cpu.h> 178c2ecf20Sopenharmony_ci#include <asm/cpu-type.h> 188c2ecf20Sopenharmony_ci#include <asm/processor.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#include <asm/dec/prom.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ciint (*__rex_bootinit)(void); 248c2ecf20Sopenharmony_ciint (*__rex_bootread)(void); 258c2ecf20Sopenharmony_ciint (*__rex_getbitmap)(memmap *); 268c2ecf20Sopenharmony_ciunsigned long *(*__rex_slot_address)(int); 278c2ecf20Sopenharmony_civoid *(*__rex_gettcinfo)(void); 288c2ecf20Sopenharmony_ciint (*__rex_getsysid)(void); 298c2ecf20Sopenharmony_civoid (*__rex_clear_cache)(void); 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ciint (*__prom_getchar)(void); 328c2ecf20Sopenharmony_cichar *(*__prom_getenv)(char *); 338c2ecf20Sopenharmony_ciint (*__prom_printf)(char *, ...); 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ciint (*__pmax_open)(char*, int); 368c2ecf20Sopenharmony_ciint (*__pmax_lseek)(int, long, int); 378c2ecf20Sopenharmony_ciint (*__pmax_read)(int, void *, int); 388c2ecf20Sopenharmony_ciint (*__pmax_close)(int); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci/* 428c2ecf20Sopenharmony_ci * Detect which PROM the DECSTATION has, and set the callback vectors 438c2ecf20Sopenharmony_ci * appropriately. 448c2ecf20Sopenharmony_ci */ 458c2ecf20Sopenharmony_civoid __init which_prom(s32 magic, s32 *prom_vec) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci /* 488c2ecf20Sopenharmony_ci * No sign of the REX PROM's magic number means we assume a non-REX 498c2ecf20Sopenharmony_ci * machine (i.e. we're on a DS2100/3100, DS5100 or DS5000/2xx) 508c2ecf20Sopenharmony_ci */ 518c2ecf20Sopenharmony_ci if (prom_is_rex(magic)) { 528c2ecf20Sopenharmony_ci /* 538c2ecf20Sopenharmony_ci * Set up prom abstraction structure with REX entry points. 548c2ecf20Sopenharmony_ci */ 558c2ecf20Sopenharmony_ci __rex_bootinit = 568c2ecf20Sopenharmony_ci (void *)(long)*(prom_vec + REX_PROM_BOOTINIT); 578c2ecf20Sopenharmony_ci __rex_bootread = 588c2ecf20Sopenharmony_ci (void *)(long)*(prom_vec + REX_PROM_BOOTREAD); 598c2ecf20Sopenharmony_ci __rex_getbitmap = 608c2ecf20Sopenharmony_ci (void *)(long)*(prom_vec + REX_PROM_GETBITMAP); 618c2ecf20Sopenharmony_ci __prom_getchar = 628c2ecf20Sopenharmony_ci (void *)(long)*(prom_vec + REX_PROM_GETCHAR); 638c2ecf20Sopenharmony_ci __prom_getenv = 648c2ecf20Sopenharmony_ci (void *)(long)*(prom_vec + REX_PROM_GETENV); 658c2ecf20Sopenharmony_ci __rex_getsysid = 668c2ecf20Sopenharmony_ci (void *)(long)*(prom_vec + REX_PROM_GETSYSID); 678c2ecf20Sopenharmony_ci __rex_gettcinfo = 688c2ecf20Sopenharmony_ci (void *)(long)*(prom_vec + REX_PROM_GETTCINFO); 698c2ecf20Sopenharmony_ci __prom_printf = 708c2ecf20Sopenharmony_ci (void *)(long)*(prom_vec + REX_PROM_PRINTF); 718c2ecf20Sopenharmony_ci __rex_slot_address = 728c2ecf20Sopenharmony_ci (void *)(long)*(prom_vec + REX_PROM_SLOTADDR); 738c2ecf20Sopenharmony_ci __rex_clear_cache = 748c2ecf20Sopenharmony_ci (void *)(long)*(prom_vec + REX_PROM_CLEARCACHE); 758c2ecf20Sopenharmony_ci } else { 768c2ecf20Sopenharmony_ci /* 778c2ecf20Sopenharmony_ci * Set up prom abstraction structure with non-REX entry points. 788c2ecf20Sopenharmony_ci */ 798c2ecf20Sopenharmony_ci __prom_getchar = (void *)PMAX_PROM_GETCHAR; 808c2ecf20Sopenharmony_ci __prom_getenv = (void *)PMAX_PROM_GETENV; 818c2ecf20Sopenharmony_ci __prom_printf = (void *)PMAX_PROM_PRINTF; 828c2ecf20Sopenharmony_ci __pmax_open = (void *)PMAX_PROM_OPEN; 838c2ecf20Sopenharmony_ci __pmax_lseek = (void *)PMAX_PROM_LSEEK; 848c2ecf20Sopenharmony_ci __pmax_read = (void *)PMAX_PROM_READ; 858c2ecf20Sopenharmony_ci __pmax_close = (void *)PMAX_PROM_CLOSE; 868c2ecf20Sopenharmony_ci } 878c2ecf20Sopenharmony_ci} 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_civoid __init prom_init(void) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci extern void dec_machine_halt(void); 928c2ecf20Sopenharmony_ci static const char cpu_msg[] __initconst = 938c2ecf20Sopenharmony_ci "Sorry, this kernel is compiled for a wrong CPU type!\n"; 948c2ecf20Sopenharmony_ci s32 argc = fw_arg0; 958c2ecf20Sopenharmony_ci s32 *argv = (void *)fw_arg1; 968c2ecf20Sopenharmony_ci u32 magic = fw_arg2; 978c2ecf20Sopenharmony_ci s32 *prom_vec = (void *)fw_arg3; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci /* 1008c2ecf20Sopenharmony_ci * Determine which PROM we have 1018c2ecf20Sopenharmony_ci * (and therefore which machine we're on!) 1028c2ecf20Sopenharmony_ci */ 1038c2ecf20Sopenharmony_ci which_prom(magic, prom_vec); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci if (prom_is_rex(magic)) 1068c2ecf20Sopenharmony_ci rex_clear_cache(); 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci /* Register the early console. */ 1098c2ecf20Sopenharmony_ci register_prom_console(); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci /* Were we compiled with the right CPU option? */ 1128c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_R3000) 1138c2ecf20Sopenharmony_ci if ((current_cpu_type() == CPU_R4000SC) || 1148c2ecf20Sopenharmony_ci (current_cpu_type() == CPU_R4400SC)) { 1158c2ecf20Sopenharmony_ci static const char r4k_msg[] __initconst = 1168c2ecf20Sopenharmony_ci "Please recompile with \"CONFIG_CPU_R4x00 = y\".\n"; 1178c2ecf20Sopenharmony_ci printk(cpu_msg); 1188c2ecf20Sopenharmony_ci printk(r4k_msg); 1198c2ecf20Sopenharmony_ci dec_machine_halt(); 1208c2ecf20Sopenharmony_ci } 1218c2ecf20Sopenharmony_ci#endif 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_R4X00) 1248c2ecf20Sopenharmony_ci if ((current_cpu_type() == CPU_R3000) || 1258c2ecf20Sopenharmony_ci (current_cpu_type() == CPU_R3000A)) { 1268c2ecf20Sopenharmony_ci static const char r3k_msg[] __initconst = 1278c2ecf20Sopenharmony_ci "Please recompile with \"CONFIG_CPU_R3000 = y\".\n"; 1288c2ecf20Sopenharmony_ci printk(cpu_msg); 1298c2ecf20Sopenharmony_ci printk(r3k_msg); 1308c2ecf20Sopenharmony_ci dec_machine_halt(); 1318c2ecf20Sopenharmony_ci } 1328c2ecf20Sopenharmony_ci#endif 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci prom_meminit(magic); 1358c2ecf20Sopenharmony_ci prom_identify_arch(magic); 1368c2ecf20Sopenharmony_ci prom_init_cmdline(argc, argv, magic); 1378c2ecf20Sopenharmony_ci} 138