00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <agnix/agnix.h>
00015 #include <agnix/spinlock.h>
00016 #include <agnix/math64.h>
00017 #include <agnix/resources.h>
00018 #include <agnix/console.h>
00019 #include <agnix/counters.h>
00020 #include <asm/atomic.h>
00021
00022 #define MOD_NAME "CNT: "
00023
00024 #define COUNTER_LOCK(cnt) u32 flags; do { spin_lock_irqsave(&cnt->cnt_lock, flags); } while(0)
00025 #define COUNTER_UNLOCK(cnt) do { spin_unlock_irqrestore(&cnt->cnt_lock, flags); } while(0)
00026
00027 int counters_resource_desc;
00028
00029 struct counter_s counters[MAX_COUNTERS];
00030
00031 u32 counters_bitmap[COUNTERS_BITMAP_LEN];
00032
00033 struct resource_s counters_resource = {
00034 .resource_name = "counters",
00035 .resource_bitmap = counters_bitmap,
00036 .resource_len = COUNTERS_BITMAP_LEN,
00037 };
00038
00039 void counter_32_bit_read(struct counter_s *counter, u32 *counter_val)
00040 {
00041 counter_val[0] = atomic_read(counter->cnt_val);
00042 }
00043
00044 void counter_32_bit_write(struct counter_s *counter, u32 *counter_new)
00045 {
00046 atomic_write(counter->cnt_val, counter_new[0]);
00047 }
00048
00049 void counter_32_bit_add(struct counter_s *counter, u32 *counter_add)
00050 {
00051 atomic_add(counter->cnt_val, counter_add[0]);
00052 }
00053
00054 void counter_32_bit_sub(struct counter_s *counter, u32 *counter_sub)
00055 {
00056 atomic_sub(counter->cnt_val, counter_sub[0]);
00057 }
00058
00059 void counter_32_bit_inc(struct counter_s *counter)
00060 {
00061 atomic_inc(counter->cnt_val);
00062 }
00063
00064 void counter_32_bit_dec(struct counter_s *counter)
00065 {
00066 atomic_dec(counter->cnt_val);
00067 }
00068
00069 void counter_64_bit_read(struct counter_s *counter, u32 *counter_val)
00070 {
00071 COUNTER_LOCK(counter);
00072 counter_val[0] = counter->cnt_val[0];
00073 counter_val[1] = counter->cnt_val[1];
00074 COUNTER_UNLOCK(counter);
00075 }
00076
00077 void counter_64_bit_write(struct counter_s *counter, u32 *counter_new)
00078 {
00079 COUNTER_LOCK(counter);
00080 counter->cnt_val[0] = counter_new[0];
00081 counter->cnt_val[1] = counter_new[1];
00082 COUNTER_UNLOCK(counter);
00083 }
00084
00085 void counter_64_bit_add(struct counter_s *counter, u32 *counter_add)
00086 {
00087 COUNTER_LOCK(counter);
00088 add_64_64(counter->cnt_val, counter->cnt_val, counter_add);
00089 COUNTER_UNLOCK(counter);
00090 }
00091
00092 void counter_64_bit_sub(struct counter_s *counter, u32 *counter_sub)
00093 {
00094 COUNTER_LOCK(counter);
00095 sub_64_64(counter->cnt_val, counter->cnt_val, counter_sub);
00096 COUNTER_UNLOCK(counter);
00097 }
00098
00099 void counter_64_bit_inc(struct counter_s *counter)
00100 {
00101 COUNTER_LOCK(counter);
00102 add_64_32(counter->cnt_val, counter->cnt_val, 1);
00103 COUNTER_UNLOCK(counter);
00104 }
00105
00106 void counter_64_bit_dec(struct counter_s *counter)
00107 {
00108 COUNTER_LOCK(counter);
00109 sub_64_32(counter->cnt_val, counter->cnt_val, 1);
00110 COUNTER_UNLOCK(counter);
00111 }
00112
00113 struct counter_ops_s counter_32_bit_ops = {
00114 .cnt_read = counter_32_bit_read,
00115 .cnt_write = counter_32_bit_write,
00116 .cnt_add = counter_32_bit_add,
00117 .cnt_sub = counter_32_bit_sub,
00118 .cnt_inc = counter_32_bit_inc,
00119 .cnt_dec = counter_32_bit_dec
00120 };
00121
00122 struct counter_ops_s counter_64_bit_ops = {
00123 .cnt_read = counter_64_bit_read,
00124 .cnt_write = counter_64_bit_write,
00125 .cnt_add = counter_64_bit_add,
00126 .cnt_sub = counter_64_bit_sub,
00127 .cnt_inc = counter_64_bit_inc,
00128 .cnt_dec = counter_64_bit_dec
00129 };
00130
00131 int put_free_counter(int counter_desc)
00132 {
00133 return put_free_resource(counters_resource_desc, counter_desc);
00134 }
00135
00136 int get_free_counter(void)
00137 {
00138 return get_free_resource(counters_resource_desc);
00139 }
00140
00141 int register_counter(int counter_type, const char *counter_name)
00142 {
00143 int counter_desc;
00144
00145 if ((counter_desc = get_free_counter()) < 0)
00146 return -1;
00147
00148 switch(counter_type) {
00149 case COUNTER_TYPE_32_BIT:
00150 printk(MOD_NAME "registering 32 bit ");
00151 counters[counter_desc].cnt_ops = &counter_32_bit_ops;
00152 break;
00153
00154 case COUNTER_TYPE_64_BIT:
00155 printk(MOD_NAME "registering 64 bit ");
00156 counters[counter_desc].cnt_ops = &counter_64_bit_ops;
00157 break;
00158
00159 default:
00160 return -1;
00161 }
00162
00163 printk("%s counter\n", counter_name);
00164 counters[counter_desc].cnt_name = counter_name;
00165
00166 return counter_desc;
00167 }
00168
00169 int counters_init(void)
00170 {
00171 printk(MOD_NAME "initializing system counters\n");
00172
00173 counters_resource_desc = register_resource(&counters_resource);
00174 counters_sys_init();
00175
00176 return 0;
00177 }