1/* 2 * Copyright 2001 Mike Corrigan, IBM Corp 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 */ 9#include <linux/types.h> 10#include <linux/threads.h> 11#include <linux/module.h> 12#include <linux/bitops.h> 13#include <asm/processor.h> 14#include <asm/ptrace.h> 15#include <asm/abs_addr.h> 16#include <asm/lppaca.h> 17#include <asm/iseries/it_lp_reg_save.h> 18#include <asm/paca.h> 19#include <asm/iseries/lpar_map.h> 20#include <asm/iseries/it_lp_queue.h> 21 22#include "naca.h" 23#include "vpd_areas.h" 24#include "spcomm_area.h" 25#include "ipl_parms.h" 26#include "processor_vpd.h" 27#include "release_data.h" 28#include "it_exp_vpd_panel.h" 29#include "it_lp_naca.h" 30 31/* The HvReleaseData is the root of the information shared between 32 * the hypervisor and Linux. 33 */ 34struct HvReleaseData hvReleaseData = { 35 .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */ 36 .xSize = sizeof(struct HvReleaseData), 37 .xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas), 38 .xSlicNacaAddr = &naca, /* 64-bit Naca address */ 39 .xMsNucDataOffset = LPARMAP_PHYS, 40 .xFlags = HVREL_TAGSINACTIVE /* tags inactive */ 41 /* 64 bit */ 42 /* shared processors */ 43 /* HMT allowed */ 44 | 6, /* TEMP: This allows non-GA driver */ 45 .xVrmIndex = 4, /* We are v5r2m0 */ 46 .xMinSupportedPlicVrmIndex = 3, /* v5r1m0 */ 47 .xMinCompatablePlicVrmIndex = 3, /* v5r1m0 */ 48 .xVrmName = { 0xd3, 0x89, 0x95, 0xa4, /* "Linux 2.4.64" ebcdic */ 49 0xa7, 0x40, 0xf2, 0x4b, 50 0xf4, 0x4b, 0xf6, 0xf4 }, 51}; 52 53/* 54 * The NACA. The first dword of the naca is required by the iSeries 55 * hypervisor to point to itVpdAreas. The hypervisor finds the NACA 56 * through the pointer in hvReleaseData. 57 */ 58struct naca_struct naca = { 59 .xItVpdAreas = &itVpdAreas, 60 .xRamDisk = 0, 61 .xRamDiskSize = 0, 62}; 63 64extern void system_reset_iSeries(void); 65extern void machine_check_iSeries(void); 66extern void data_access_iSeries(void); 67extern void instruction_access_iSeries(void); 68extern void hardware_interrupt_iSeries(void); 69extern void alignment_iSeries(void); 70extern void program_check_iSeries(void); 71extern void fp_unavailable_iSeries(void); 72extern void decrementer_iSeries(void); 73extern void trap_0a_iSeries(void); 74extern void trap_0b_iSeries(void); 75extern void system_call_iSeries(void); 76extern void single_step_iSeries(void); 77extern void trap_0e_iSeries(void); 78extern void performance_monitor_iSeries(void); 79extern void data_access_slb_iSeries(void); 80extern void instruction_access_slb_iSeries(void); 81 82struct ItLpNaca itLpNaca = { 83 .xDesc = 0xd397d581, /* "LpNa" ebcdic */ 84 .xSize = 0x0400, /* size of ItLpNaca */ 85 .xIntHdlrOffset = 0x0300, /* offset to int array */ 86 .xMaxIntHdlrEntries = 19, /* # ents */ 87 .xPrimaryLpIndex = 0, /* Part # of primary */ 88 .xServiceLpIndex = 0, /* Part # of serv */ 89 .xLpIndex = 0, /* Part # of me */ 90 .xMaxLpQueues = 0, /* # of LP queues */ 91 .xLpQueueOffset = 0x100, /* offset of start of LP queues */ 92 .xPirEnvironMode = 0, /* Piranha stuff */ 93 .xPirConsoleMode = 0, 94 .xPirDasdMode = 0, 95 .flags = 0, 96 .xSpVpdFormat = 0, 97 .xIntProcRatio = 0, 98 .xPlicVrmIndex = 0, /* VRM index of PLIC */ 99 .xMinSupportedSlicVrmInd = 0, /* min supported SLIC */ 100 .xMinCompatableSlicVrmInd = 0, /* min compat SLIC */ 101 .xLoadAreaAddr = 0, /* 64-bit addr of load area */ 102 .xLoadAreaChunks = 0, /* chunks for load area */ 103 .xPaseSysCallCRMask = 0, /* PASE mask */ 104 .xSlicSegmentTablePtr = 0, /* seg table */ 105 .xOldLpQueue = { 0 }, /* Old LP Queue */ 106 .xInterruptHdlr = { 107 (u64)system_reset_iSeries, /* 0x100 System Reset */ 108 (u64)machine_check_iSeries, /* 0x200 Machine Check */ 109 (u64)data_access_iSeries, /* 0x300 Data Access */ 110 (u64)instruction_access_iSeries, /* 0x400 Instruction Access */ 111 (u64)hardware_interrupt_iSeries, /* 0x500 External */ 112 (u64)alignment_iSeries, /* 0x600 Alignment */ 113 (u64)program_check_iSeries, /* 0x700 Program Check */ 114 (u64)fp_unavailable_iSeries, /* 0x800 FP Unavailable */ 115 (u64)decrementer_iSeries, /* 0x900 Decrementer */ 116 (u64)trap_0a_iSeries, /* 0xa00 Trap 0A */ 117 (u64)trap_0b_iSeries, /* 0xb00 Trap 0B */ 118 (u64)system_call_iSeries, /* 0xc00 System Call */ 119 (u64)single_step_iSeries, /* 0xd00 Single Step */ 120 (u64)trap_0e_iSeries, /* 0xe00 Trap 0E */ 121 (u64)performance_monitor_iSeries,/* 0xf00 Performance Monitor */ 122 0, /* int 0x1000 */ 123 0, /* int 0x1010 */ 124 0, /* int 0x1020 CPU ctls */ 125 (u64)hardware_interrupt_iSeries, /* SC Ret Hdlr */ 126 (u64)data_access_slb_iSeries, /* 0x380 D-SLB */ 127 (u64)instruction_access_slb_iSeries /* 0x480 I-SLB */ 128 } 129}; 130 131/* May be filled in by the hypervisor so cannot end up in the BSS */ 132struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data"))); 133 134/* May be filled in by the hypervisor so cannot end up in the BSS */ 135struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data"))); 136 137#define maxPhysicalProcessors 32 138 139struct IoHriProcessorVpd xIoHriProcessorVpd[maxPhysicalProcessors] = { 140 { 141 .xInstCacheOperandSize = 32, 142 .xDataCacheOperandSize = 32, 143 .xProcFreq = 50000000, 144 .xTimeBaseFreq = 50000000, 145 .xPVR = 0x3600 146 } 147}; 148 149/* Space for Main Store Vpd 27,200 bytes */ 150/* May be filled in by the hypervisor so cannot end up in the BSS */ 151u64 xMsVpd[3400] __attribute__((__section__(".data"))); 152 153/* Space for Recovery Log Buffer */ 154/* May be filled in by the hypervisor so cannot end up in the BSS */ 155u64 xRecoveryLogBuffer[32] __attribute__((__section__(".data"))); 156 157struct SpCommArea xSpCommArea = { 158 .xDesc = 0xE2D7C3C2, 159 .xFormat = 1, 160}; 161 162/* The LparMap data is now located at offset 0x6000 in head.S 163 * It was put there so that the HvReleaseData could address it 164 * with a 32-bit offset as required by the iSeries hypervisor 165 * 166 * The Naca has a pointer to the ItVpdAreas. The hypervisor finds 167 * the Naca via the HvReleaseData area. The HvReleaseData has the 168 * offset into the Naca of the pointer to the ItVpdAreas. 169 */ 170struct ItVpdAreas itVpdAreas = { 171 .xSlicDesc = 0xc9a3e5c1, /* "ItVA" */ 172 .xSlicSize = sizeof(struct ItVpdAreas), 173 .xSlicVpdEntries = ItVpdMaxEntries, /* # VPD array entries */ 174 .xSlicDmaEntries = ItDmaMaxEntries, /* # DMA array entries */ 175 .xSlicMaxLogicalProcs = NR_CPUS * 2, /* Max logical procs */ 176 .xSlicMaxPhysicalProcs = maxPhysicalProcessors, /* Max physical procs */ 177 .xSlicDmaToksOffset = offsetof(struct ItVpdAreas, xPlicDmaToks), 178 .xSlicVpdAdrsOffset = offsetof(struct ItVpdAreas, xSlicVpdAdrs), 179 .xSlicDmaLensOffset = offsetof(struct ItVpdAreas, xPlicDmaLens), 180 .xSlicVpdLensOffset = offsetof(struct ItVpdAreas, xSlicVpdLens), 181 .xSlicMaxSlotLabels = 0, /* max slot labels */ 182 .xSlicMaxLpQueues = 1, /* max LP queues */ 183 .xPlicDmaLens = { 0 }, /* DMA lengths */ 184 .xPlicDmaToks = { 0 }, /* DMA tokens */ 185 .xSlicVpdLens = { /* VPD lengths */ 186 0,0,0, /* 0 - 2 */ 187 sizeof(xItExtVpdPanel), /* 3 Extended VPD */ 188 sizeof(struct paca_struct), /* 4 length of Paca */ 189 0, /* 5 */ 190 sizeof(struct ItIplParmsReal),/* 6 length of IPL parms */ 191 26992, /* 7 length of MS VPD */ 192 0, /* 8 */ 193 sizeof(struct ItLpNaca),/* 9 length of LP Naca */ 194 0, /* 10 */ 195 256, /* 11 length of Recovery Log Buf */ 196 sizeof(struct SpCommArea), /* 12 length of SP Comm Area */ 197 0,0,0, /* 13 - 15 */ 198 sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */ 199 0,0,0,0,0,0, /* 17 - 22 */ 200 sizeof(struct hvlpevent_queue), /* 23 length of Lp Queue */ 201 0,0 /* 24 - 25 */ 202 }, 203 .xSlicVpdAdrs = { /* VPD addresses */ 204 0,0,0, /* 0 - 2 */ 205 &xItExtVpdPanel, /* 3 Extended VPD */ 206 &paca[0], /* 4 first Paca */ 207 0, /* 5 */ 208 &xItIplParmsReal, /* 6 IPL parms */ 209 &xMsVpd, /* 7 MS Vpd */ 210 0, /* 8 */ 211 &itLpNaca, /* 9 LpNaca */ 212 0, /* 10 */ 213 &xRecoveryLogBuffer, /* 11 Recovery Log Buffer */ 214 &xSpCommArea, /* 12 SP Comm Area */ 215 0,0,0, /* 13 - 15 */ 216 &xIoHriProcessorVpd, /* 16 Proc Vpd */ 217 0,0,0,0,0,0, /* 17 - 22 */ 218 &hvlpevent_queue, /* 23 Lp Queue */ 219 0,0 220 } 221}; 222 223struct ItLpRegSave iseries_reg_save[] = { 224 [0 ... (NR_CPUS-1)] = { 225 .xDesc = 0xd397d9e2, /* "LpRS" */ 226 .xSize = sizeof(struct ItLpRegSave), 227 }, 228}; 229