#include #include #include #include "memsize.h" #include "memMarco.h" u64 gMemDiagStartAddr; EXPORT_SYMBOL(gMemDiagStartAddr); u64 gDiagAvailAddr; u64 gMemDiagRegionSize; EXPORT_SYMBOL(gMemDiagRegionSize); u64 gMemDiagTOLMAddr; EXPORT_SYMBOL(gMemDiagTOLMAddr); u64 gMemDiagTOHMAddr; EXPORT_SYMBOL(gMemDiagTOHMAddr); u64 gMemDiagTSEGAddr; EXPORT_SYMBOL(gMemDiagTSEGAddr); u64 gMemDiagTSEGSize; EXPORT_SYMBOL(gMemDiagTSEGSize); /******************************************************************************* * PROCEDURE * * NAME: memGetMemConfig * SUMMARY: This procedure will get memory configuration from the integrated memory controller * SCOPE: public * * DESCRIPTION: This function will read memory configuration infomation * form the pci configuration register of the integrated memory controller * * RETURNS: the total size of memory * * NOTES: * */ #define DIMMMTR_DIMM_POP_BIT (1<<14) // DIMMTR_[0:2]: DIMM Memory Technology #define DIMMMTR_RANK_CNT_MASK (1<<13 | 1<<12) // RANK_CNT 00- SR, 01-DR, 10-QR #define DIMMMTR_RANK_CNT_SHIFT 1 #define DIMMMTR_RA_WIDTH_MASK (1<<4 | 1<<3 | 1<<2) // Row #define DIMMMTR_RA_WIDTH_SHIFT 12-2 #define DIMMMTR_CA_WIDTH_MASK (1<<1 | 1<<0) // Col #define DIMMMTR_CA_WIDTH_SHIFT 10 u64 memGetMemConfig(void) { struct pci_dev* pdev = NULL; u32 valDimm; u64 sizeMem; int numRow; int numCol; //int numBank; int pdev_mem_targets[3]={ 0x3cab, 0x3cac, 0x3cad }; int idxPdev; sizeMem = 0; for(idxPdev=0; idxPdev< (sizeof(pdev_mem_targets) / sizeof(pdev_mem_targets[0])); idxPdev++){ pdev = pci_get_device(0x8086, pdev_mem_targets[idxPdev], NULL); // if (pdev != NULL){ pci_read_config_dword(pdev, 0x80, &valDimm); printk("pci_get_device(0x8086, 0x%x) (addr:0x80) = 0x%x\n",pdev_mem_targets[idxPdev], valDimm); if ( valDimm & DIMMMTR_DIMM_POP_BIT ) { numRow= 1 << (DIMMMTR_RA_WIDTH_SHIFT + (valDimm & DIMMMTR_RA_WIDTH_MASK)); numCol= 1 << (DIMMMTR_CA_WIDTH_SHIFT + (valDimm & DIMMMTR_CA_WIDTH_MASK)); printk ("numRow: %d * numCol %d = size %d MB\n",numRow, numCol, (int)( ((u64)numRow * (u64)numCol) >> 20)); sizeMem += ((u64)numRow * (u64)numCol); } }else{ printk("pci_get_device(0x8086, 0x%x): FAIL\n",pdev_mem_targets[idxPdev]); } } printk ("Mem: 0x%Lx , %d MB\n", sizeMem, (int)( sizeMem >> 20)); return sizeMem; } #define UINT64_MAX (18446744073709551615ULL) //#define MEM_JF_CORE_DID 0x3728 #define MEM_JF_CORE_DID 0x3c28 #define MEM_JF_CORE_REG_TOLM_OFFSET 0xD0 // 32bit #define MEM_JF_CORE_REG_TOHM_OFFSET 0xD4 #define MEM_JF_CORE_REG_TOHML_OFFSET 0xD4 #define MEM_JF_CORE_REG_TOHMH_OFFSET 0xD8 #define MEM_JF_CORE_REG_TOHMH_START 0x100000000 #define MEM_JF_CORE_REG_TOM_MASK 0xFC000000 #define MEM_JF_CORE_REG_TSEGCTRL_OFFSET 0xA8 #define MEM_JF_CORE_REG_TSEG_ENABLE 0x00000001 #define MEM_JF_CORE_REG_TSEG_ADDR_MASK 0xFFF00000 #define MEM_JF_CORE_REG_TSEG_SIZE_MASK 0x0000000E #define MEM_JF_CORE_REG_TSEG_SIZE_BASE 0x00080000 void memSetDiagStartAddr(u64 start_addr) { struct pci_dev* pdev = NULL; u32 obs_val; if( (start_addr == UINT64_MAX) | (start_addr == 0) ) gMemDiagStartAddr = (u64)(num_physpages << PAGE_SHIFT); else gMemDiagStartAddr = start_addr; if (memGetMemConfig() != 0) { gMemDiagRegionSize = memGetMemConfig() - (u64)(num_physpages << PAGE_SHIFT); } else { gMemDiagRegionSize = 512 * MB - (u64)(num_physpages << PAGE_SHIFT); } printk(" = kernel size %Ld M, memory size %Ld M\n", (gMemDiagStartAddr >> 20) , (gMemDiagRegionSize >> 20)); pdev = pci_get_device(PCI_VENDOR_ID_INTEL, MEM_JF_CORE_DID, pdev); if(pdev != NULL) { pci_read_config_dword(pdev, MEM_JF_CORE_REG_TOLM_OFFSET, &obs_val); gMemDiagTOLMAddr = obs_val & MEM_JF_CORE_REG_TOM_MASK; pci_read_config_dword(pdev, MEM_JF_CORE_REG_TOHM_OFFSET+4, &obs_val); gMemDiagTOHMAddr = obs_val; pci_read_config_dword(pdev, MEM_JF_CORE_REG_TOHM_OFFSET, &obs_val); gMemDiagTOHMAddr = (obs_val & MEM_JF_CORE_REG_TOM_MASK) | (gMemDiagTOHMAddr << 32); printk("gMemDiagTOLMAddr: 0x%Lx, gMemDiagTOHMAddr: 0x%Lx \n",gMemDiagTOLMAddr,gMemDiagTOHMAddr); pci_read_config_dword(pdev, MEM_JF_CORE_REG_TSEGCTRL_OFFSET, &obs_val); printk(" MEM_JF_CORE_REG_TSEGCTRL_OFFSET(0x%x): 0x%x (%d)\n",MEM_JF_CORE_REG_TSEGCTRL_OFFSET,obs_val, (obs_val & MEM_JF_CORE_REG_TSEG_ENABLE)); if(obs_val & MEM_JF_CORE_REG_TSEG_ENABLE) { gMemDiagTSEGAddr = obs_val & MEM_JF_CORE_REG_TSEG_ADDR_MASK; if((gMemDiagTSEGAddr > gMemDiagTOLMAddr) && (gMemDiagTSEGAddr < MEM_JF_CORE_REG_TOHMH_START)) { gMemDiagTSEGAddr = 0; gMemDiagTSEGSize = 0; } else { gMemDiagTSEGSize = MEM_JF_CORE_REG_TSEG_SIZE_BASE << ((obs_val & MEM_JF_CORE_REG_TSEG_SIZE_MASK) / 2); } } printk("gMemDiagTSEGAddr: 0x%Lx, gMemDiagTSEGSize: 0x%Lx \n",gMemDiagTSEGAddr,gMemDiagTSEGSize); } printk(" + kernel size %Ld M, memory size %Ld M\n", (gMemDiagStartAddr >> 20) , (gMemDiagRegionSize >> 20)); if((gMemDiagStartAddr + gMemDiagRegionSize) > gMemDiagTOLMAddr) { gMemDiagRegionSize = gMemDiagTOLMAddr - gMemDiagStartAddr; printk(" -> kernel size %Ld M, memory size %Ld M\n", (gMemDiagStartAddr >> 20) , (gMemDiagRegionSize >> 20)); if(gMemDiagTOHMAddr > 0) { gMemDiagRegionSize += gMemDiagTOHMAddr - MEM_JF_CORE_REG_TOHMH_START; printk(" ->> kernel size %Ld M, memory size %Ld M\n", (gMemDiagStartAddr >> 20) , (gMemDiagRegionSize >> 20)); } } printk(" * kernel size %Lx, memory size %Lx\n", gMemDiagStartAddr, gMemDiagRegionSize); printk(" - kernel size %Ld M, memory size %Ld M\n", (gMemDiagStartAddr >> 20) , (gMemDiagRegionSize >> 20)); }