Home | History | Annotate | Download | only in legacynet
      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