1use core::cell::Cell;
37use kernel::hil::flash::{self, Flash};
38use kernel::hil::hasher::{self, Hasher};
39use kernel::utilities::cells::{MapCell, OptionalCell, TakeCell};
40use kernel::utilities::leasable_buffer::{SubSlice, SubSliceMut};
41use kernel::ErrorCode;
42use tickv::AsyncTicKV;
43
44pub trait KeyType: Eq + Copy + Clone + Sized + AsRef<[u8]> + AsMut<[u8]> {}
47
48impl KeyType for [u8; 8] {}
49
50pub trait KVSystemClient<K: KeyType> {
52 fn generate_key_complete(
58 &self,
59 result: Result<(), ErrorCode>,
60 unhashed_key: SubSliceMut<'static, u8>,
61 key_buf: &'static mut K,
62 );
63
64 fn append_key_complete(
70 &self,
71 result: Result<(), ErrorCode>,
72 key: &'static mut K,
73 value: SubSliceMut<'static, u8>,
74 );
75
76 fn get_value_complete(
82 &self,
83 result: Result<(), ErrorCode>,
84 key: &'static mut K,
85 ret_buf: SubSliceMut<'static, u8>,
86 );
87
88 fn invalidate_key_complete(&self, result: Result<(), ErrorCode>, key: &'static mut K);
93
94 fn garbage_collect_complete(&self, result: Result<(), ErrorCode>);
98}
99
100pub trait KVSystem<'a> {
101 type K: KeyType;
103
104 fn set_client(&self, client: &'a dyn KVSystemClient<Self::K>);
106
107 fn generate_key(
115 &self,
116 unhashed_key: SubSliceMut<'static, u8>,
117 key_buf: &'static mut Self::K,
118 ) -> Result<(), (SubSliceMut<'static, u8>, &'static mut Self::K, ErrorCode)>;
119
120 fn append_key(
140 &self,
141 key: &'static mut Self::K,
142 value: SubSliceMut<'static, u8>,
143 ) -> Result<(), (&'static mut Self::K, SubSliceMut<'static, u8>, ErrorCode)>;
144
145 fn get_value(
160 &self,
161 key: &'static mut Self::K,
162 ret_buf: SubSliceMut<'static, u8>,
163 ) -> Result<(), (&'static mut Self::K, SubSliceMut<'static, u8>, ErrorCode)>;
164
165 fn invalidate_key(
178 &self,
179 key: &'static mut Self::K,
180 ) -> Result<(), (&'static mut Self::K, ErrorCode)>;
181
182 fn garbage_collect(&self) -> Result<(), ErrorCode>;
196}
197
198#[derive(Clone, Copy, PartialEq, Debug)]
199enum Operation {
200 None,
201 Init,
202 GetKey,
203 AppendKey,
204 InvalidateKey,
205 GarbageCollect,
206}
207
208pub struct TickFSFlashCtrl<'a, F: Flash + 'static> {
219 flash: &'a F,
220 flash_read_buffer: TakeCell<'static, F::Page>,
221 region_offset: usize,
222}
223
224impl<'a, F: Flash> TickFSFlashCtrl<'a, F> {
225 pub fn new(
226 flash: &'a F,
227 flash_read_buffer: &'static mut F::Page,
228 region_offset: usize,
229 ) -> TickFSFlashCtrl<'a, F> {
230 Self {
231 flash,
232 flash_read_buffer: TakeCell::new(flash_read_buffer),
233 region_offset,
234 }
235 }
236}
237
238impl<F: Flash, const PAGE_SIZE: usize> tickv::flash_controller::FlashController<PAGE_SIZE>
239 for TickFSFlashCtrl<'_, F>
240{
241 fn read_region(
242 &self,
243 region_number: usize,
244 _buf: &mut [u8; PAGE_SIZE],
245 ) -> Result<(), tickv::error_codes::ErrorCode> {
246 if self
247 .flash
248 .read_page(
249 self.region_offset + region_number,
250 self.flash_read_buffer.take().unwrap(),
251 )
252 .is_err()
253 {
254 Err(tickv::error_codes::ErrorCode::ReadFail)
255 } else {
256 Err(tickv::error_codes::ErrorCode::ReadNotReady(region_number))
257 }
258 }
259
260 fn write(&self, address: usize, buf: &[u8]) -> Result<(), tickv::error_codes::ErrorCode> {
261 let data_buf = self.flash_read_buffer.take().unwrap();
262
263 for (i, d) in buf.iter().enumerate() {
264 data_buf.as_mut()[i + (address % PAGE_SIZE)] = *d;
265 }
266
267 if self
268 .flash
269 .write_page(self.region_offset + (address / PAGE_SIZE), data_buf)
270 .is_err()
271 {
272 return Err(tickv::error_codes::ErrorCode::WriteFail);
273 }
274
275 Err(tickv::error_codes::ErrorCode::WriteNotReady(address))
276 }
277
278 fn erase_region(&self, region_number: usize) -> Result<(), tickv::error_codes::ErrorCode> {
279 let _ = self.flash.erase_page(self.region_offset + region_number);
280
281 Err(tickv::error_codes::ErrorCode::EraseNotReady(region_number))
282 }
283}
284
285pub type TicKVKeyType = [u8; 8];
286
287pub struct TicKVSystem<'a, F: Flash + 'static, H: Hasher<'a, 8>, const PAGE_SIZE: usize> {
289 tickv: AsyncTicKV<'a, TickFSFlashCtrl<'a, F>, PAGE_SIZE>,
291 hasher: &'a H,
293 operation: Cell<Operation>,
295 next_operation: Cell<Operation>,
297 unhashed_key_buffer: MapCell<SubSliceMut<'static, u8>>,
300 key_buffer: TakeCell<'static, [u8; 8]>,
302 value_buffer: MapCell<SubSliceMut<'static, u8>>,
305 client: OptionalCell<&'a dyn KVSystemClient<TicKVKeyType>>,
307}
308
309impl<'a, F: Flash, H: Hasher<'a, 8>, const PAGE_SIZE: usize> TicKVSystem<'a, F, H, PAGE_SIZE> {
310 pub fn new(
311 flash: &'a F,
312 hasher: &'a H,
313 tickfs_read_buf: &'static mut [u8; PAGE_SIZE],
314 flash_read_buffer: &'static mut F::Page,
315 region_offset: usize,
316 flash_size: usize,
317 ) -> TicKVSystem<'a, F, H, PAGE_SIZE> {
318 let tickv = AsyncTicKV::<TickFSFlashCtrl<F>, PAGE_SIZE>::new(
319 TickFSFlashCtrl::new(flash, flash_read_buffer, region_offset),
320 tickfs_read_buf,
321 flash_size,
322 );
323
324 Self {
325 tickv,
326 hasher,
327 operation: Cell::new(Operation::None),
328 next_operation: Cell::new(Operation::None),
329 unhashed_key_buffer: MapCell::empty(),
330 key_buffer: TakeCell::empty(),
331 value_buffer: MapCell::empty(),
332 client: OptionalCell::empty(),
333 }
334 }
335
336 pub fn initialise(&self) {
337 let _ret = self.tickv.initialise(0x7bc9f7ff4f76f244);
338 self.operation.set(Operation::Init);
339 }
340
341 fn complete_init(&self) {
342 self.operation.set(Operation::None);
343 match self.next_operation.get() {
344 Operation::None | Operation::Init => {}
345 Operation::GetKey => {
346 if let Err((key, value, error)) = self.get_value(
347 self.key_buffer.take().unwrap(),
348 self.value_buffer.take().unwrap(),
349 ) {
350 self.client.map(move |cb| {
351 cb.get_value_complete(Err(error), key, value);
352 });
353 }
354 }
355 Operation::AppendKey => {
356 if let Err((key, value, error)) = self.append_key(
357 self.key_buffer.take().unwrap(),
358 self.value_buffer.take().unwrap(),
359 ) {
360 self.client.map(move |cb| {
361 cb.append_key_complete(Err(error), key, value);
362 });
363 }
364 }
365 Operation::InvalidateKey => {
366 if let Err((key, error)) = self.invalidate_key(self.key_buffer.take().unwrap()) {
367 self.client.map(move |cb| {
368 cb.invalidate_key_complete(Err(error), key);
369 });
370 }
371 }
372 Operation::GarbageCollect => {
373 if let Err(error) = self.garbage_collect() {
374 self.client.map(move |cb| {
375 cb.garbage_collect_complete(Err(error));
376 });
377 }
378 }
379 }
380 self.next_operation.set(Operation::None);
381 }
382}
383
384impl<'a, F: Flash, H: Hasher<'a, 8>, const PAGE_SIZE: usize> hasher::Client<8>
385 for TicKVSystem<'a, F, H, PAGE_SIZE>
386{
387 fn add_mut_data_done(&self, _result: Result<(), ErrorCode>, data: SubSliceMut<'static, u8>) {
388 self.unhashed_key_buffer.replace(data);
389 self.hasher.run(self.key_buffer.take().unwrap()).unwrap();
390 }
391
392 fn add_data_done(&self, _result: Result<(), ErrorCode>, _data: SubSlice<'static, u8>) {}
393
394 fn hash_done(&self, _result: Result<(), ErrorCode>, digest: &'static mut [u8; 8]) {
395 self.client.map(move |cb| {
396 cb.generate_key_complete(Ok(()), self.unhashed_key_buffer.take().unwrap(), digest);
397 });
398
399 self.hasher.clear_data();
400 }
401}
402
403impl<'a, F: Flash, H: Hasher<'a, 8>, const PAGE_SIZE: usize> flash::Client<F>
404 for TicKVSystem<'a, F, H, PAGE_SIZE>
405{
406 fn read_complete(&self, pagebuffer: &'static mut F::Page, _result: Result<(), flash::Error>) {
407 self.tickv.set_read_buffer(pagebuffer.as_mut());
408 self.tickv
409 .tickv
410 .controller
411 .flash_read_buffer
412 .replace(pagebuffer);
413 let (ret, tickv_buf, tickv_buf_len) = self.tickv.continue_operation();
414
415 tickv_buf.map(|buf| {
417 let mut val_buf = SubSliceMut::new(buf);
418 if tickv_buf_len > 0 {
419 val_buf.slice(0..tickv_buf_len);
422 }
423 self.value_buffer.replace(val_buf);
424 });
425
426 match self.operation.get() {
427 Operation::Init => match ret {
428 Ok(tickv::success_codes::SuccessCode::Complete)
429 | Ok(tickv::success_codes::SuccessCode::Written) => {
430 self.complete_init();
431 }
432 _ => {}
433 },
434 Operation::GetKey => {
435 match ret {
436 Ok(tickv::success_codes::SuccessCode::Complete)
437 | Ok(tickv::success_codes::SuccessCode::Written) => {
438 self.operation.set(Operation::None);
441 self.client.map(|cb| {
442 cb.get_value_complete(
443 Ok(()),
444 self.key_buffer.take().unwrap(),
445 self.value_buffer.take().unwrap(),
446 );
447 });
448 }
449 Err(tickv::error_codes::ErrorCode::BufferTooSmall(_)) => {
450 self.operation.set(Operation::None);
456 self.client.map(|cb| {
457 cb.get_value_complete(
458 Err(ErrorCode::SIZE),
459 self.key_buffer.take().unwrap(),
460 self.value_buffer.take().unwrap(),
461 );
462 });
463 }
464 Err(tickv::error_codes::ErrorCode::ReadNotReady(_)) => {
465 }
470 Err(tickv::error_codes::ErrorCode::EraseNotReady(_)) | Ok(_) => {}
471 Err(e) => {
472 let get_tock_err = match e {
473 tickv::error_codes::ErrorCode::KeyNotFound => ErrorCode::NOSUPPORT,
474 _ => ErrorCode::FAIL,
475 };
476 self.operation.set(Operation::None);
477 self.client.map(|cb| {
478 cb.get_value_complete(
479 Err(get_tock_err),
480 self.key_buffer.take().unwrap(),
481 self.value_buffer.take().unwrap(),
482 );
483 });
484 }
485 }
486 }
487 Operation::AppendKey => {
488 match ret {
489 Ok(tickv::success_codes::SuccessCode::Complete)
490 | Ok(tickv::success_codes::SuccessCode::Written) => {
491 self.operation.set(Operation::None);
494 }
495 Ok(tickv::success_codes::SuccessCode::Queued) => {}
496 Err(tickv::error_codes::ErrorCode::ReadNotReady(_))
497 | Err(tickv::error_codes::ErrorCode::WriteNotReady(_))
498 | Err(tickv::error_codes::ErrorCode::EraseNotReady(_)) => {
499 }
501 Err(e) => {
502 self.operation.set(Operation::None);
503
504 let tock_hil_error = match e {
505 tickv::error_codes::ErrorCode::KeyAlreadyExists => ErrorCode::NOSUPPORT,
506 tickv::error_codes::ErrorCode::RegionFull => ErrorCode::NOMEM,
507 tickv::error_codes::ErrorCode::FlashFull => ErrorCode::NOMEM,
508 _ => ErrorCode::FAIL,
509 };
510 self.client.map(|cb| {
511 cb.append_key_complete(
512 Err(tock_hil_error),
513 self.key_buffer.take().unwrap(),
514 self.value_buffer.take().unwrap(),
515 );
516 });
517 }
518 }
519 }
520 Operation::InvalidateKey => match ret {
521 Ok(tickv::success_codes::SuccessCode::Complete)
522 | Ok(tickv::success_codes::SuccessCode::Written) => {
523 self.operation.set(Operation::None);
525 }
526 Ok(tickv::success_codes::SuccessCode::Queued) => {}
527 Err(tickv::error_codes::ErrorCode::ReadNotReady(_))
528 | Err(tickv::error_codes::ErrorCode::WriteNotReady(_))
529 | Err(tickv::error_codes::ErrorCode::EraseNotReady(_)) => {
530 }
532 Err(e) => {
533 self.operation.set(Operation::None);
534
535 let tock_hil_error = match e {
536 tickv::error_codes::ErrorCode::KeyNotFound => ErrorCode::NOSUPPORT,
537 _ => ErrorCode::FAIL,
538 };
539 self.client.map(|cb| {
540 cb.invalidate_key_complete(
541 Err(tock_hil_error),
542 self.key_buffer.take().unwrap(),
543 );
544 });
545 }
546 },
547 Operation::GarbageCollect => match ret {
548 Ok(tickv::success_codes::SuccessCode::Complete)
549 | Ok(tickv::success_codes::SuccessCode::Written) => {
550 self.operation.set(Operation::None);
551 self.client.map(|cb| {
552 cb.garbage_collect_complete(Ok(()));
553 });
554 }
555 _ => {}
556 },
557 _ => unreachable!(),
558 }
559 }
560
561 fn write_complete(&self, pagebuffer: &'static mut F::Page, _result: Result<(), flash::Error>) {
562 self.tickv
563 .tickv
564 .controller
565 .flash_read_buffer
566 .replace(pagebuffer);
567
568 match self.operation.get() {
569 Operation::Init => {
570 self.complete_init();
571 }
572 Operation::AppendKey => {
573 self.operation.set(Operation::None);
574 self.client.map(|cb| {
575 cb.append_key_complete(
576 Ok(()),
577 self.key_buffer.take().unwrap(),
578 self.value_buffer.take().unwrap(),
579 );
580 });
581 }
582 Operation::InvalidateKey => {
583 self.operation.set(Operation::None);
584 self.client.map(|cb| {
585 cb.invalidate_key_complete(Ok(()), self.key_buffer.take().unwrap());
586 });
587 }
588 _ => unreachable!(),
589 }
590 }
591
592 fn erase_complete(&self, _result: Result<(), flash::Error>) {
593 let (ret, tickv_buf, tickv_buf_len) = self.tickv.continue_operation();
594
595 tickv_buf.map(|buf| {
597 let mut val_buf = SubSliceMut::new(buf);
598 if tickv_buf_len > 0 {
599 val_buf.slice(0..tickv_buf_len);
602 }
603 self.value_buffer.replace(val_buf);
604 });
605
606 match self.operation.get() {
607 Operation::Init => match ret {
608 Ok(tickv::success_codes::SuccessCode::Complete)
609 | Ok(tickv::success_codes::SuccessCode::Written) => {
610 self.complete_init();
611 }
612 _ => {}
613 },
614 Operation::GarbageCollect => match ret {
615 Ok(tickv::success_codes::SuccessCode::Complete)
616 | Ok(tickv::success_codes::SuccessCode::Written) => {
617 self.operation.set(Operation::None);
618 self.client.map(|cb| {
619 cb.garbage_collect_complete(Ok(()));
620 });
621 }
622 _ => {}
623 },
624 _ => unreachable!(),
625 }
626 }
627}
628
629impl<'a, F: Flash, H: Hasher<'a, 8>, const PAGE_SIZE: usize> KVSystem<'a>
630 for TicKVSystem<'a, F, H, PAGE_SIZE>
631{
632 type K = TicKVKeyType;
633
634 fn set_client(&self, client: &'a dyn KVSystemClient<Self::K>) {
635 self.client.set(client);
636 }
637
638 fn generate_key(
639 &self,
640 unhashed_key: SubSliceMut<'static, u8>,
641 key: &'static mut Self::K,
642 ) -> Result<(), (SubSliceMut<'static, u8>, &'static mut Self::K, ErrorCode)> {
643 match self.hasher.add_mut_data(unhashed_key) {
644 Ok(_) => {
645 self.key_buffer.replace(key);
646 Ok(())
647 }
648 Err((e, buf)) => Err((buf, key, e)),
649 }
650 }
651
652 fn append_key(
653 &self,
654 key: &'static mut Self::K,
655 value: SubSliceMut<'static, u8>,
656 ) -> Result<(), (&'static mut [u8; 8], SubSliceMut<'static, u8>, ErrorCode)> {
657 match self.operation.get() {
658 Operation::None => {
659 self.operation.set(Operation::AppendKey);
660
661 let length = value.len();
662 match self
663 .tickv
664 .append_key(u64::from_be_bytes(*key), value.take(), length)
665 {
666 Ok(_ret) => {
667 self.key_buffer.replace(key);
668 Ok(())
669 }
670 Err((buf, e)) => {
671 let tock_error = match e {
672 tickv::error_codes::ErrorCode::ObjectTooLarge => ErrorCode::SIZE,
673 _ => ErrorCode::FAIL,
674 };
675 Err((key, SubSliceMut::new(buf), tock_error))
676 }
677 }
678 }
679 Operation::Init => {
680 self.next_operation.set(Operation::AppendKey);
683 self.key_buffer.replace(key);
684 self.value_buffer.replace(value);
685 Ok(())
686 }
687 _ => {
688 Err((key, value, ErrorCode::BUSY))
690 }
691 }
692 }
693
694 fn get_value(
695 &self,
696 key: &'static mut Self::K,
697 value: SubSliceMut<'static, u8>,
698 ) -> Result<(), (&'static mut [u8; 8], SubSliceMut<'static, u8>, ErrorCode)> {
699 if value.is_sliced() {
700 return Err((key, value, ErrorCode::SIZE));
701 }
702 match self.operation.get() {
703 Operation::None => {
704 self.operation.set(Operation::GetKey);
705
706 match self.tickv.get_key(u64::from_be_bytes(*key), value.take()) {
707 Ok(_ret) => {
708 self.key_buffer.replace(key);
709 Ok(())
710 }
711 Err((buf, _e)) => Err((key, SubSliceMut::new(buf), ErrorCode::FAIL)),
712 }
713 }
714 Operation::Init => {
715 self.next_operation.set(Operation::GetKey);
718 self.key_buffer.replace(key);
719 self.value_buffer.replace(value);
720 Ok(())
721 }
722 _ => {
723 Err((key, value, ErrorCode::BUSY))
725 }
726 }
727 }
728
729 fn invalidate_key(
730 &self,
731 key: &'static mut Self::K,
732 ) -> Result<(), (&'static mut Self::K, ErrorCode)> {
733 match self.operation.get() {
734 Operation::None => {
735 self.operation.set(Operation::InvalidateKey);
736
737 match self.tickv.invalidate_key(u64::from_be_bytes(*key)) {
738 Ok(_ret) => {
739 self.key_buffer.replace(key);
740 Ok(())
741 }
742 Err(_e) => Err((key, ErrorCode::FAIL)),
743 }
744 }
745 Operation::Init => {
746 self.next_operation.set(Operation::InvalidateKey);
749 self.key_buffer.replace(key);
750 Ok(())
751 }
752 _ => {
753 Err((key, ErrorCode::BUSY))
755 }
756 }
757 }
758
759 fn garbage_collect(&self) -> Result<(), ErrorCode> {
760 match self.operation.get() {
761 Operation::None => {
762 self.operation.set(Operation::GarbageCollect);
763 self.tickv
764 .garbage_collect()
765 .and(Ok(()))
766 .or(Err(ErrorCode::FAIL))
767 }
768 Operation::Init => {
769 self.next_operation.set(Operation::GarbageCollect);
772 Ok(())
773 }
774 _ => {
775 Err(ErrorCode::BUSY)
777 }
778 }
779 }
780}