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 match self.get_value(
347 self.key_buffer.take().unwrap(),
348 self.value_buffer.take().unwrap(),
349 ) {
350 Err((key, value, error)) => {
351 self.client.map(move |cb| {
352 cb.get_value_complete(Err(error), key, value);
353 });
354 }
355 _ => {}
356 }
357 }
358 Operation::AppendKey => {
359 match self.append_key(
360 self.key_buffer.take().unwrap(),
361 self.value_buffer.take().unwrap(),
362 ) {
363 Err((key, value, error)) => {
364 self.client.map(move |cb| {
365 cb.append_key_complete(Err(error), key, value);
366 });
367 }
368 _ => {}
369 }
370 }
371 Operation::InvalidateKey => {
372 match self.invalidate_key(self.key_buffer.take().unwrap()) {
373 Err((key, error)) => {
374 self.client.map(move |cb| {
375 cb.invalidate_key_complete(Err(error), key);
376 });
377 }
378 _ => {}
379 }
380 }
381 Operation::GarbageCollect => match self.garbage_collect() {
382 Err(error) => {
383 self.client.map(move |cb| {
384 cb.garbage_collect_complete(Err(error));
385 });
386 }
387 _ => {}
388 },
389 }
390 self.next_operation.set(Operation::None);
391 }
392}
393
394impl<'a, F: Flash, H: Hasher<'a, 8>, const PAGE_SIZE: usize> hasher::Client<8>
395 for TicKVSystem<'a, F, H, PAGE_SIZE>
396{
397 fn add_mut_data_done(&self, _result: Result<(), ErrorCode>, data: SubSliceMut<'static, u8>) {
398 self.unhashed_key_buffer.replace(data);
399 self.hasher.run(self.key_buffer.take().unwrap()).unwrap();
400 }
401
402 fn add_data_done(&self, _result: Result<(), ErrorCode>, _data: SubSlice<'static, u8>) {}
403
404 fn hash_done(&self, _result: Result<(), ErrorCode>, digest: &'static mut [u8; 8]) {
405 self.client.map(move |cb| {
406 cb.generate_key_complete(Ok(()), self.unhashed_key_buffer.take().unwrap(), digest);
407 });
408
409 self.hasher.clear_data();
410 }
411}
412
413impl<'a, F: Flash, H: Hasher<'a, 8>, const PAGE_SIZE: usize> flash::Client<F>
414 for TicKVSystem<'a, F, H, PAGE_SIZE>
415{
416 fn read_complete(&self, pagebuffer: &'static mut F::Page, _result: Result<(), flash::Error>) {
417 self.tickv.set_read_buffer(pagebuffer.as_mut());
418 self.tickv
419 .tickv
420 .controller
421 .flash_read_buffer
422 .replace(pagebuffer);
423 let (ret, tickv_buf, tickv_buf_len) = self.tickv.continue_operation();
424
425 tickv_buf.map(|buf| {
427 let mut val_buf = SubSliceMut::new(buf);
428 if tickv_buf_len > 0 {
429 val_buf.slice(0..tickv_buf_len);
432 }
433 self.value_buffer.replace(val_buf);
434 });
435
436 match self.operation.get() {
437 Operation::Init => match ret {
438 Ok(tickv::success_codes::SuccessCode::Complete)
439 | Ok(tickv::success_codes::SuccessCode::Written) => {
440 self.complete_init();
441 }
442 _ => {}
443 },
444 Operation::GetKey => {
445 match ret {
446 Ok(tickv::success_codes::SuccessCode::Complete)
447 | Ok(tickv::success_codes::SuccessCode::Written) => {
448 self.operation.set(Operation::None);
451 self.client.map(|cb| {
452 cb.get_value_complete(
453 Ok(()),
454 self.key_buffer.take().unwrap(),
455 self.value_buffer.take().unwrap(),
456 );
457 });
458 }
459 Err(tickv::error_codes::ErrorCode::BufferTooSmall(_)) => {
460 self.operation.set(Operation::None);
466 self.client.map(|cb| {
467 cb.get_value_complete(
468 Err(ErrorCode::SIZE),
469 self.key_buffer.take().unwrap(),
470 self.value_buffer.take().unwrap(),
471 );
472 });
473 }
474 Err(tickv::error_codes::ErrorCode::ReadNotReady(_)) => {
475 }
480 Err(tickv::error_codes::ErrorCode::EraseNotReady(_)) | Ok(_) => {}
481 Err(e) => {
482 let get_tock_err = match e {
483 tickv::error_codes::ErrorCode::KeyNotFound => ErrorCode::NOSUPPORT,
484 _ => ErrorCode::FAIL,
485 };
486 self.operation.set(Operation::None);
487 self.client.map(|cb| {
488 cb.get_value_complete(
489 Err(get_tock_err),
490 self.key_buffer.take().unwrap(),
491 self.value_buffer.take().unwrap(),
492 );
493 });
494 }
495 }
496 }
497 Operation::AppendKey => {
498 match ret {
499 Ok(tickv::success_codes::SuccessCode::Complete)
500 | Ok(tickv::success_codes::SuccessCode::Written) => {
501 self.operation.set(Operation::None);
504 }
505 Ok(tickv::success_codes::SuccessCode::Queued) => {}
506 Err(tickv::error_codes::ErrorCode::ReadNotReady(_))
507 | Err(tickv::error_codes::ErrorCode::WriteNotReady(_))
508 | Err(tickv::error_codes::ErrorCode::EraseNotReady(_)) => {
509 }
511 Err(e) => {
512 self.operation.set(Operation::None);
513
514 let tock_hil_error = match e {
515 tickv::error_codes::ErrorCode::KeyAlreadyExists => ErrorCode::NOSUPPORT,
516 tickv::error_codes::ErrorCode::RegionFull => ErrorCode::NOMEM,
517 tickv::error_codes::ErrorCode::FlashFull => ErrorCode::NOMEM,
518 _ => ErrorCode::FAIL,
519 };
520 self.client.map(|cb| {
521 cb.append_key_complete(
522 Err(tock_hil_error),
523 self.key_buffer.take().unwrap(),
524 self.value_buffer.take().unwrap(),
525 );
526 });
527 }
528 }
529 }
530 Operation::InvalidateKey => match ret {
531 Ok(tickv::success_codes::SuccessCode::Complete)
532 | Ok(tickv::success_codes::SuccessCode::Written) => {
533 self.operation.set(Operation::None);
535 }
536 Ok(tickv::success_codes::SuccessCode::Queued) => {}
537 Err(tickv::error_codes::ErrorCode::ReadNotReady(_))
538 | Err(tickv::error_codes::ErrorCode::WriteNotReady(_))
539 | Err(tickv::error_codes::ErrorCode::EraseNotReady(_)) => {
540 }
542 Err(e) => {
543 self.operation.set(Operation::None);
544
545 let tock_hil_error = match e {
546 tickv::error_codes::ErrorCode::KeyNotFound => ErrorCode::NOSUPPORT,
547 _ => ErrorCode::FAIL,
548 };
549 self.client.map(|cb| {
550 cb.invalidate_key_complete(
551 Err(tock_hil_error),
552 self.key_buffer.take().unwrap(),
553 );
554 });
555 }
556 },
557 Operation::GarbageCollect => match ret {
558 Ok(tickv::success_codes::SuccessCode::Complete)
559 | Ok(tickv::success_codes::SuccessCode::Written) => {
560 self.operation.set(Operation::None);
561 self.client.map(|cb| {
562 cb.garbage_collect_complete(Ok(()));
563 });
564 }
565 _ => {}
566 },
567 _ => unreachable!(),
568 }
569 }
570
571 fn write_complete(&self, pagebuffer: &'static mut F::Page, _result: Result<(), flash::Error>) {
572 self.tickv
573 .tickv
574 .controller
575 .flash_read_buffer
576 .replace(pagebuffer);
577
578 match self.operation.get() {
579 Operation::Init => {
580 self.complete_init();
581 }
582 Operation::AppendKey => {
583 self.operation.set(Operation::None);
584 self.client.map(|cb| {
585 cb.append_key_complete(
586 Ok(()),
587 self.key_buffer.take().unwrap(),
588 self.value_buffer.take().unwrap(),
589 );
590 });
591 }
592 Operation::InvalidateKey => {
593 self.operation.set(Operation::None);
594 self.client.map(|cb| {
595 cb.invalidate_key_complete(Ok(()), self.key_buffer.take().unwrap());
596 });
597 }
598 _ => unreachable!(),
599 }
600 }
601
602 fn erase_complete(&self, _result: Result<(), flash::Error>) {
603 let (ret, tickv_buf, tickv_buf_len) = self.tickv.continue_operation();
604
605 tickv_buf.map(|buf| {
607 let mut val_buf = SubSliceMut::new(buf);
608 if tickv_buf_len > 0 {
609 val_buf.slice(0..tickv_buf_len);
612 }
613 self.value_buffer.replace(val_buf);
614 });
615
616 match self.operation.get() {
617 Operation::Init => match ret {
618 Ok(tickv::success_codes::SuccessCode::Complete)
619 | Ok(tickv::success_codes::SuccessCode::Written) => {
620 self.complete_init();
621 }
622 _ => {}
623 },
624 Operation::GarbageCollect => match ret {
625 Ok(tickv::success_codes::SuccessCode::Complete)
626 | Ok(tickv::success_codes::SuccessCode::Written) => {
627 self.operation.set(Operation::None);
628 self.client.map(|cb| {
629 cb.garbage_collect_complete(Ok(()));
630 });
631 }
632 _ => {}
633 },
634 _ => unreachable!(),
635 }
636 }
637}
638
639impl<'a, F: Flash, H: Hasher<'a, 8>, const PAGE_SIZE: usize> KVSystem<'a>
640 for TicKVSystem<'a, F, H, PAGE_SIZE>
641{
642 type K = TicKVKeyType;
643
644 fn set_client(&self, client: &'a dyn KVSystemClient<Self::K>) {
645 self.client.set(client);
646 }
647
648 fn generate_key(
649 &self,
650 unhashed_key: SubSliceMut<'static, u8>,
651 key: &'static mut Self::K,
652 ) -> Result<(), (SubSliceMut<'static, u8>, &'static mut Self::K, ErrorCode)> {
653 match self.hasher.add_mut_data(unhashed_key) {
654 Ok(_) => {
655 self.key_buffer.replace(key);
656 Ok(())
657 }
658 Err((e, buf)) => Err((buf, key, e)),
659 }
660 }
661
662 fn append_key(
663 &self,
664 key: &'static mut Self::K,
665 value: SubSliceMut<'static, u8>,
666 ) -> Result<(), (&'static mut [u8; 8], SubSliceMut<'static, u8>, ErrorCode)> {
667 match self.operation.get() {
668 Operation::None => {
669 self.operation.set(Operation::AppendKey);
670
671 let length = value.len();
672 match self
673 .tickv
674 .append_key(u64::from_be_bytes(*key), value.take(), length)
675 {
676 Ok(_ret) => {
677 self.key_buffer.replace(key);
678 Ok(())
679 }
680 Err((buf, e)) => {
681 let tock_error = match e {
682 tickv::error_codes::ErrorCode::ObjectTooLarge => ErrorCode::SIZE,
683 _ => ErrorCode::FAIL,
684 };
685 Err((key, SubSliceMut::new(buf), tock_error))
686 }
687 }
688 }
689 Operation::Init => {
690 self.next_operation.set(Operation::AppendKey);
693 self.key_buffer.replace(key);
694 self.value_buffer.replace(value);
695 Ok(())
696 }
697 _ => {
698 Err((key, value, ErrorCode::BUSY))
700 }
701 }
702 }
703
704 fn get_value(
705 &self,
706 key: &'static mut Self::K,
707 value: SubSliceMut<'static, u8>,
708 ) -> Result<(), (&'static mut [u8; 8], SubSliceMut<'static, u8>, ErrorCode)> {
709 if value.is_sliced() {
710 return Err((key, value, ErrorCode::SIZE));
711 }
712 match self.operation.get() {
713 Operation::None => {
714 self.operation.set(Operation::GetKey);
715
716 match self.tickv.get_key(u64::from_be_bytes(*key), value.take()) {
717 Ok(_ret) => {
718 self.key_buffer.replace(key);
719 Ok(())
720 }
721 Err((buf, _e)) => Err((key, SubSliceMut::new(buf), ErrorCode::FAIL)),
722 }
723 }
724 Operation::Init => {
725 self.next_operation.set(Operation::GetKey);
728 self.key_buffer.replace(key);
729 self.value_buffer.replace(value);
730 Ok(())
731 }
732 _ => {
733 Err((key, value, ErrorCode::BUSY))
735 }
736 }
737 }
738
739 fn invalidate_key(
740 &self,
741 key: &'static mut Self::K,
742 ) -> Result<(), (&'static mut Self::K, ErrorCode)> {
743 match self.operation.get() {
744 Operation::None => {
745 self.operation.set(Operation::InvalidateKey);
746
747 match self.tickv.invalidate_key(u64::from_be_bytes(*key)) {
748 Ok(_ret) => {
749 self.key_buffer.replace(key);
750 Ok(())
751 }
752 Err(_e) => Err((key, ErrorCode::FAIL)),
753 }
754 }
755 Operation::Init => {
756 self.next_operation.set(Operation::InvalidateKey);
759 self.key_buffer.replace(key);
760 Ok(())
761 }
762 _ => {
763 Err((key, ErrorCode::BUSY))
765 }
766 }
767 }
768
769 fn garbage_collect(&self) -> Result<(), ErrorCode> {
770 match self.operation.get() {
771 Operation::None => {
772 self.operation.set(Operation::GarbageCollect);
773 self.tickv
774 .garbage_collect()
775 .and(Ok(()))
776 .or(Err(ErrorCode::FAIL))
777 }
778 Operation::Init => {
779 self.next_operation.set(Operation::GarbageCollect);
782 Ok(())
783 }
784 _ => {
785 Err(ErrorCode::BUSY)
787 }
788 }
789 }
790}