1230557Sjimharris/*- 2230557Sjimharris * BSD LICENSE 3230557Sjimharris * 4230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 5230557Sjimharris * All rights reserved. 6230557Sjimharris * 7230557Sjimharris * Redistribution and use in source and binary forms, with or without 8230557Sjimharris * modification, are permitted provided that the following conditions 9230557Sjimharris * are met: 10230557Sjimharris * 11230557Sjimharris * * Redistributions of source code must retain the above copyright 12230557Sjimharris * notice, this list of conditions and the following disclaimer. 13230557Sjimharris * * Redistributions in binary form must reproduce the above copyright 14230557Sjimharris * notice, this list of conditions and the following disclaimer in 15230557Sjimharris * the documentation and/or other materials provided with the 16230557Sjimharris * distribution. 17230557Sjimharris * 18230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29230557Sjimharris */ 30230557Sjimharris 31230557Sjimharris#include <sys/cdefs.h> 32230557Sjimharris__FBSDID("$FreeBSD$"); 33230557Sjimharris 34230557Sjimharris#include <dev/isci/isci.h> 35230557Sjimharris#include <vm/vm.h> 36230557Sjimharris#include <vm/pmap.h> 37230557Sjimharris#include <machine/vmparam.h> 38230557Sjimharris#include <machine/pc/bios.h> 39230557Sjimharris#include <dev/isci/scil/scu_bios_definitions.h> 40230557Sjimharris 41230557Sjimharrisstruct pcir_header 42230557Sjimharris{ 43230557Sjimharris uint32_t signature; 44230557Sjimharris uint16_t vendor_id; 45230557Sjimharris uint16_t device_id; 46230557Sjimharris uint16_t reserved; 47230557Sjimharris uint16_t struct_length; 48230557Sjimharris uint8_t struct_revision; 49230557Sjimharris uint8_t cc_interface; 50230557Sjimharris uint8_t cc_subclass; 51230557Sjimharris uint8_t cc_baseclass; 52230557Sjimharris uint16_t image_length; 53230557Sjimharris uint16_t code_revision; 54230557Sjimharris uint8_t code_type; 55230557Sjimharris uint8_t indicator; 56230557Sjimharris uint16_t reserved1; 57230557Sjimharris}; 58230557Sjimharris 59230557Sjimharrisstruct rom_header 60230557Sjimharris{ 61230557Sjimharris uint8_t signature_byte[2]; 62230557Sjimharris uint8_t rom_length; 63230557Sjimharris uint8_t jmp_code; 64230557Sjimharris uint16_t entry_address; 65230557Sjimharris uint8_t reserved[0x12]; 66230557Sjimharris uint16_t pcir_pointer; 67230557Sjimharris uint16_t pnp_pointer; 68230557Sjimharris}; 69230557Sjimharris 70230557Sjimharrisstruct oem_parameters_table 71230557Sjimharris{ 72230557Sjimharris uint8_t signature[4]; /* "$OEM" */ 73230557Sjimharris struct revision 74230557Sjimharris { 75230557Sjimharris uint16_t major:8; /* bits [7:0] */ 76230557Sjimharris uint16_t minor:8; /* bits [8:15] */ 77230557Sjimharris } revision; 78230557Sjimharris 79230557Sjimharris uint16_t length; 80230557Sjimharris uint8_t checksum; 81230557Sjimharris uint8_t reserved1; 82230557Sjimharris uint16_t reserved2; 83230557Sjimharris uint8_t data[1]; 84230557Sjimharris}; 85230557Sjimharris 86230557Sjimharrisvoid 87230557Sjimharrisisci_get_oem_parameters(struct isci_softc *isci) 88230557Sjimharris{ 89230557Sjimharris uint32_t OROM_PHYSICAL_ADDRESS_START = 0xC0000; 90230557Sjimharris uint32_t OROM_SEARCH_LENGTH = 0x30000; 91230557Sjimharris uint16_t OROM_SIGNATURE = 0xAA55; 92230557Sjimharris uint32_t OROM_SIZE = 512; 93230557Sjimharris uint8_t *orom_start = 94230557Sjimharris (uint8_t *)BIOS_PADDRTOVADDR(OROM_PHYSICAL_ADDRESS_START); 95230557Sjimharris uint32_t offset = 0; 96230557Sjimharris 97230557Sjimharris while (offset < OROM_SEARCH_LENGTH) { 98230557Sjimharris 99230557Sjimharris /* Look for the OROM signature at the beginning of every 100230557Sjimharris * 512-byte block in the OROM region 101230557Sjimharris */ 102230557Sjimharris if (*(uint16_t*)(orom_start + offset) == OROM_SIGNATURE) { 103230557Sjimharris uint32_t *rom; 104230557Sjimharris struct rom_header *rom_header; 105230557Sjimharris struct pcir_header *pcir_header; 106230557Sjimharris uint16_t vendor_id = isci->pci_common_header.vendor_id; 107230557Sjimharris uint16_t device_id = isci->pci_common_header.device_id; 108230557Sjimharris 109230557Sjimharris rom = (uint32_t *)(orom_start + offset); 110230557Sjimharris rom_header = (struct rom_header *)rom; 111230557Sjimharris pcir_header = (struct pcir_header *) 112230557Sjimharris ((uint8_t*)rom + rom_header->pcir_pointer); 113230557Sjimharris 114230557Sjimharris /* OROM signature was found. Now check if the PCI 115230557Sjimharris * device and vendor IDs match. 116230557Sjimharris */ 117230557Sjimharris if (pcir_header->vendor_id == vendor_id && 118230557Sjimharris pcir_header->device_id == device_id) 119230557Sjimharris { 120230557Sjimharris /* OROM for this PCI device was found. Search 121230557Sjimharris * this 512-byte block for the $OEM string, 122230557Sjimharris * which will mark the beginning of the OEM 123230557Sjimharris * parameter block. 124230557Sjimharris */ 125230557Sjimharris uint8_t oem_sig[4] = {'$', 'O', 'E', 'M'}; 126230557Sjimharris int dword_index; 127230557Sjimharris 128230557Sjimharris for (dword_index = 0; 129230557Sjimharris dword_index < OROM_SIZE/sizeof(uint32_t); 130230557Sjimharris dword_index++) 131230557Sjimharris if (rom[dword_index] == *(uint32_t *)oem_sig) { 132230557Sjimharris /* $OEM signature string was found. Now copy the OEM parameter block 133230557Sjimharris * into the struct ISCI_CONTROLLER objects. After the controllers are 134230557Sjimharris * constructed, we will pass this OEM parameter data to the SCI core 135230557Sjimharris * controller. 136230557Sjimharris */ 137230557Sjimharris struct oem_parameters_table *oem = 138230557Sjimharris (struct oem_parameters_table *)&rom[dword_index]; 139230557Sjimharris SCI_BIOS_OEM_PARAM_BLOCK_T *oem_data = 140230557Sjimharris (SCI_BIOS_OEM_PARAM_BLOCK_T *)oem->data; 141230557Sjimharris int index; 142230557Sjimharris 143230557Sjimharris isci->oem_parameters_found = TRUE; 144230557Sjimharris isci_log_message(1, "ISCI", "oem_data->header.num_elements = %d\n", 145230557Sjimharris oem_data->header.num_elements); 146230557Sjimharris 147230557Sjimharris for (index = 0; index < oem_data->header.num_elements; index++) 148230557Sjimharris { 149230557Sjimharris memcpy(&isci->controllers[index].oem_parameters.sds1, 150230557Sjimharris &oem_data->controller_element[index], 151230557Sjimharris sizeof(SCIC_SDS_OEM_PARAMETERS_T)); 152230557Sjimharris 153230557Sjimharris isci_log_message(1, "ISCI", "OEM Parameter Data for controller %d\n", 154230557Sjimharris index); 155230557Sjimharris 156230557Sjimharris for (int i = 0; i < sizeof(SCIC_SDS_OEM_PARAMETERS_T); i++) { 157230557Sjimharris uint8_t val = ((uint8_t *)&oem_data->controller_element[index])[i]; 158230557Sjimharris isci_log_message(1, "ISCI", "%02x ", val); 159230557Sjimharris } 160230557Sjimharris isci_log_message(1, "ISCI", "\n"); 161230557Sjimharris isci->controllers[index].oem_parameters_version = oem_data->header.version; 162230557Sjimharris } 163230557Sjimharris } 164230557Sjimharris 165230557Sjimharris /* No need to continue searching for another 166230557Sjimharris * OROM that matches this PCI device, so return 167230557Sjimharris * immediately. 168230557Sjimharris */ 169230557Sjimharris return; 170230557Sjimharris } 171230557Sjimharris } 172230557Sjimharris 173230557Sjimharris offset += OROM_SIZE; 174230557Sjimharris } 175230557Sjimharris} 176