1 #include "fwcfg.h" 2 #include "smp.h" 3 #include "libcflat.h" 4 5 static struct spinlock lock; 6 7 static long fw_override[FW_CFG_NUM_ENTRIES]; 8 static bool fw_override_done; 9 10 bool no_test_device; 11 read_cfg_override(void)12static void read_cfg_override(void) 13 { 14 const char *str; 15 int i; 16 17 /* Initialize to negative value that would be considered as invalid */ 18 for (i = 0; i < FW_CFG_NUM_ENTRIES; i++) 19 fw_override[i] = -1; 20 21 if ((str = getenv("NR_CPUS"))) 22 fw_override[FW_CFG_NB_CPUS] = atol(str); 23 24 /* MEMSIZE is in megabytes */ 25 if ((str = getenv("MEMSIZE"))) 26 fw_override[FW_CFG_RAM_SIZE] = atol(str) * 1024 * 1024; 27 28 if ((str = getenv("TEST_DEVICE"))) 29 no_test_device = !atol(str); 30 31 if ((str = getenv("MEMLIMIT"))) 32 fw_override[FW_CFG_MAX_RAM] = atol(str) * 1024 * 1024; 33 34 35 fw_override_done = true; 36 } 37 fwcfg_get_u(uint16_t index,int bytes)38static uint64_t fwcfg_get_u(uint16_t index, int bytes) 39 { 40 uint64_t r = 0; 41 uint8_t b; 42 int i; 43 44 if (!fw_override_done) 45 read_cfg_override(); 46 47 if (index < FW_CFG_NUM_ENTRIES && fw_override[index] >= 0) 48 return fw_override[index]; 49 50 spin_lock(&lock); 51 asm volatile ("out %0, %1" : : "a"(index), "d"((uint16_t)BIOS_CFG_IOPORT)); 52 for (i = 0; i < bytes; ++i) { 53 asm volatile ("in %1, %0" : "=a"(b) : "d"((uint16_t)(BIOS_CFG_IOPORT + 1))); 54 r |= (uint64_t)b << (i * 8); 55 } 56 spin_unlock(&lock); 57 return r; 58 } 59 fwcfg_get_u8(unsigned index)60uint8_t fwcfg_get_u8(unsigned index) 61 { 62 return fwcfg_get_u(index, 1); 63 } 64 fwcfg_get_u16(unsigned index)65uint16_t fwcfg_get_u16(unsigned index) 66 { 67 return fwcfg_get_u(index, 2); 68 } 69 fwcfg_get_u32(unsigned index)70uint32_t fwcfg_get_u32(unsigned index) 71 { 72 return fwcfg_get_u(index, 4); 73 } 74 fwcfg_get_u64(unsigned index)75uint64_t fwcfg_get_u64(unsigned index) 76 { 77 return fwcfg_get_u(index, 8); 78 } 79 fwcfg_get_nb_cpus(void)80unsigned fwcfg_get_nb_cpus(void) 81 { 82 return fwcfg_get_u16(FW_CFG_NB_CPUS); 83 } 84