1 /* ----------------------------------------------------------------------- * 2 * 3 * Copyright 2010 Intel Corporation; author: H. Peter Anvin 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 8 * Boston MA 02110-1301, USA; either version 2 of the License, or 9 * (at your option) any later version; incorporated herein by reference. 10 * 11 * ----------------------------------------------------------------------- */ 12 13 #include <stdint.h> 14 #include <stdbool.h> 15 #include <netinet/in.h> 16 #include "pxe.h" 17 18 /* Port number bitmap - port numbers 49152 (0xc000) to 57343 (0xefff) */ 19 #define PORT_NUMBER_BASE 49152 20 #define PORT_NUMBER_COUNT 8192 /* Power of 2, please */ 21 static uint32_t port_number_bitmap[PORT_NUMBER_COUNT/32]; 22 static uint16_t first_port_number /* = 0 */; 23 24 /* 25 * Bitmap functions 26 */ 27 static bool test_bit(const uint32_t *bitmap, int32_t index) 28 { 29 uint8_t st; 30 asm("btl %2,%1 ; setc %0" : "=qm" (st) : "m" (*bitmap), "r" (index)); 31 return st; 32 } 33 34 static void set_bit(uint32_t *bitmap, int32_t index) 35 { 36 asm volatile("btsl %1,%0" : "+m" (*bitmap) : "r" (index) : "memory"); 37 } 38 39 static void clr_bit(uint32_t *bitmap, int32_t index) 40 { 41 asm volatile("btcl %1,%0" : "+m" (*bitmap) : "r" (index) : "memory"); 42 } 43 44 /* 45 * Get and free a port number (host byte order) 46 */ 47 uint16_t get_port(void) 48 { 49 uint16_t port; 50 51 do { 52 port = first_port_number++; 53 first_port_number &= PORT_NUMBER_COUNT - 1; 54 } while (test_bit(port_number_bitmap, port)); 55 56 set_bit(port_number_bitmap, port); 57 return htons(port + PORT_NUMBER_BASE); 58 } 59 60 void free_port(uint16_t port) 61 { 62 port = ntohs(port) - PORT_NUMBER_BASE; 63 64 if (port >= PORT_NUMBER_COUNT) 65 return; 66 67 clr_bit(port_number_bitmap, port); 68 } 69